Consensys / gnark-crypto

gnark-crypto provides elliptic curve and pairing-based cryptography on BN, BLS12, BLS24 and BW6 curves. It also provides various algorithms (algebra, crypto) of particular interest to zero knowledge proof systems.
Apache License 2.0
502 stars 162 forks source link

Endian issue in handling eddsa private key scalar #199

Closed gzelda closed 2 years ago

gzelda commented 2 years ago

https://github.com/ConsenSys/gnark-crypto/blob/master/ecc/bn254/twistededwards/eddsa/eddsa.go#L89

code reference

    h := blake2b.Sum512(seed[:])
    for i := 0; i < 32; i++ {
        priv.randSrc[i] = h[i+32]
    }

    // prune the key
    // https://tools.ietf.org/html/rfc8032#section-5.1.5, key generation

    h[0] &= 0xF8
    h[31] &= 0x7F
    h[31] |= 0x40

    // reverse first bytes because setBytes interpret stream as big endian
    // but in eddsa specs s is the first 32 bytes in little endian
    for i, j := 0, sizeFr; i < j; i, j = i+1, j-1 {
        h[i], h[j] = h[j], h[i]
    }

explanation

h is [64]byte, and in eddsa h[:32] is scalar and h[32:] is random source. As the annotation describes, if reverse first bytes because setBytes interpret stream as big endian. We should swap h[0] with h[31] but not h[sizeFr] = h[32].

Please correct me if I understand wrongly. I can create a pr for this issue later.

gzelda commented 2 years ago

@gbotrel @ThomasPiellard Need confirmation

gbotrel commented 2 years ago

@tyGavinZJU you are correct, j should be initialized with sizeFr - 1 ; thanks for raising this issue 👍