Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nim 2.0.x devel: static generic typeclass type mismatch #373

Open
mratsim opened this issue Apr 27, 2024 · 3 comments
Open

Nim 2.0.x devel: static generic typeclass type mismatch #373

mratsim opened this issue Apr 27, 2024 · 3 comments

Comments

@mratsim
Copy link
Owner

mratsim commented Apr 27, 2024

From #370 (comment)

Overview

Command:

nim c  -d:CTT_ASM=false  --tlsEmulation=off  -d:danger  --panics:on -d:noSignalHandler  --mm:arc -d:useMalloc  --verbosity:0 --hints:off --warnings:off  --passC:-fno-semantic-interposition  --passC:-falign-functions=64  --passC:-fmerge-all-constants --threads:on  --noMain --app:staticlib  --nimMainPrefix:ctt_init_  --out:libconstantine.a --outdir:lib  --nimcache:nimcache/libconstantine_static bindings/lib_constantine.nim

It seems like there is a regression in Nim 2.0.x devel branch that breaks type-checking:

image

No issue in Nim 2.0.2 or 2.04

image

Investigation

Error

Error: type mismatch
Expression: isOne((coords: [(mres: (limbs: [0'u, 0'u, 0'u, 0'u, 0'u, 0'u])), (mres: (limbs: [
    16517514583386313282'u, 74322656156451461'u, 16683759486841714365'u,
    815493829203396097'u, 204518332920448171'u, 1306242806803223655'u]))]))
  [1] (coords: [(mres: (limbs: [0'u, 0'u, 0'u, 0'u, 0'u, 0'u])), (mres: (limbs: [
    16517514583386313282'u, 74322656156451461'u, 16683759486841714365'u,
    815493829203396097'u, 204518332920448171'u, 1306242806803223655'u]))]): QuadraticExt

Expected one of (first mismatch at [position]):
[1] func isOne(a: BigInt): SecretBool
[1] func isOne(a: ExtensionField): SecretBool
[1] func isOne(a: FF): SecretBool

The input should match:

func isOne*(a: ExtensionField): SecretBool =
## Constant-time check if one
result = CtTrue
result = result and a.coords[0].isOne()
staticFor i, 1, a.coords.len:
result = result and a.coords[i].isZero()

and ExtensionField is just a generic typeclass

type
NonResidue* = object
## Non-Residue
##
## Placeholder for the appropriate quadratic, cubic or sectic non-residue
QuadraticExt*[F] = object
## Quadratic Extension field
coords*: array[2, F]
CubicExt*[F] = object
## Cubic Extension field
coords*: array[3, F]
ExtensionField*[F] = QuadraticExt[F] or CubicExt[F]

The only potential buggy part is that it's called in a compile-time context:

func mulCheckSparse*(a: var QuadraticExt, b: static QuadraticExt) {.inline.} =
when isOne(b).bool:
discard
elif isMinusOne(b).bool:
a.neg()
elif isZero(c0(b)).bool and isOne(c1(b)).bool:

@mratsim
Copy link
Owner Author

mratsim commented Apr 28, 2024

From https://github.com/mratsim/constantine/actions/runs/8629836320/job/23654839440 in PR #368

v2.0.4 with git hash b47747d31844c6bd9af4322efe55e24fefea544c was working fine

image

@mratsim
Copy link
Owner Author

mratsim commented Apr 29, 2024

Reproduced locally, the compiler loses the concrete type here:
image

Some possibly interesting points:

  • The b input is static generic
  • The b input is instantiated via a dynamicBindSym macro
    {.experimental: "dynamicBindSym".}
    macro h2cConst*(C: static Curve, mapping: untyped, group: static Subgroup, value: untyped): untyped =
    ## Get a Hash-to-Curve constant
    ## for mapping to a elliptic curve group (G1 or G2)
    return bindSym($C & "_h2c_" & $mapping & "_" & $group & "_" & $value)
  • The isOne proc does not import directly or via its import graph the h2cConst input which might lead to generic sandwich issues

@mratsim
Copy link
Owner Author

mratsim commented Apr 29, 2024

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant