jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.19k stars 1.74k forks source link

Secret Seed Normalization #920

Closed skaht closed 4 years ago

skaht commented 4 years ago

Concerns crypto_core_ed25519_scalar_reduce() functionality when contrasted to results from Monero's sc_reduce32() and manually using the multiprecision basic calculator (bc) that yields matching results that differ from crypto_core_ed25519_scalar_reduce().

Test vector:

seed = 26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36.

Using Monero: % echo 26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36 | sc_reduce32 5f4b86fb88745966e39bf311c65ea5a6cb1caac8c6568e4d2493087db51f0d06

or try using https://xmr.llcoins.net/addresstests.html and insert the seed above into "field 2" and click "Gen 3. & 4."

Using bc:

1% echo -n 26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36 | tr "[a-f]" "[A-F]" | rev | dd conv=swab 360D1FB57D0893244D8E56C6C8AA1CCBE5424C61FADA72666E909DD81267C726

2% echo "obase=16; ibase=16; 360D1FB57D0893244D8E56C6C8AA1CCBE5424C61FADA72666E909DD81267C726 % 1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED" | bc 60D1FB57D0893244D8E56C6C8AA1CCBA6A55EC611F39BE366597488FB864B5F

3% echo -n 60D1FB57D0893244D8E56C6C8AA1CCBA6A55EC611F39BE366597488FB864B5F | wc -c 63 Need to add a leading 0 below

4% echo -n 060D1FB57D0893244D8E56C6C8AA1CCBA6A55EC611F39BE366597488FB864B5F | rev | dd conv=swab 5F4B86FB88745966E39BF311C65EA5A6CB1CAAC8C6568E4D2493087DB51F0D06 matches Monero's result

Results from libsodium crypto_core_ed25519_scalar_reduce()

b479ccb1e980ae9c940f09afef6153e117b2fe1a70a6acf690b789fea7f3d60f != 5F4B86FB88745966E39BF311C65EA5A6CB1CAAC8C6568E4D2493087DB51F0D06

results from libsodium crypto_core_ed25519_scalar_reduce() are a form of a normalization (checked 31 other test vectors), but does not appear to be from a modulo base10( 1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED) == 2^252 + 27742317777372353535851937790883648493, the order of either ed25519 or curve25519.

Is interesting to note that code from https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c#L2451 and https://github.com/monero-project/monero/blob/master/src/crypto/crypto-ops.c#L1666 appear to share remarkable lineage but there are differences.

jedisct1 commented 4 years ago
#include <stdio.h>
#include <sodium.h>

#define SC_HEX "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36"

int main(void)
{
    unsigned char nonreduced[crypto_core_ed25519_NONREDUCEDSCALARBYTES] = {0};
    unsigned char reduced[crypto_core_ed25519_SCALARBYTES];
    char          reduced_hex[crypto_core_ed25519_SCALARBYTES * 2 + 1];

    sodium_hex2bin(nonreduced, sizeof nonreduced,
                   SC_HEX, sizeof SC_HEX, NULL, NULL, NULL);
    crypto_core_ed25519_scalar_reduce(reduced, nonreduced);
    puts(sodium_bin2hex(reduced_hex, sizeof reduced_hex, reduced, sizeof reduced));

    return 0;
}

prints

5f4b86fb88745966e39bf311c65ea5a6cb1caac8c6568e4d2493087db51f0d06

Please check your code.

skaht commented 4 years ago

The issue was with the initialization unsigned char nonreduced[crypto_core_ed25519_NONREDUCEDSCALARBYTES] = {0};

Was particularly troublesome with having an outer loop of 32 test vectors.

From reading https://download.libsodium.org/doc/advanced/point-arithmetic#scalar-arithmetic-over-l, never would have figured that out.

Thanks for the assist:-)