I am trying to replicate https://monero.stackexchange.com/a/12288 "by hand" with common unix shell tools only - bc, xxd and openssl.
According to documentation for ED25519, l is 2^252 + 27742317777372353535851937790883648493.
Starting with the same secret key as in the referenced question, I first try to "reduce" the secret with modulo l:
secret=77FADBE52830D30438FF68036374C0E3FB755D0D983743BCBFB6A45962F50A09
l=1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED
reduced=$(echo "obase=16; $secret % $l" | BC_LINE_LENGTH=0 bc)
# => 1F1D7471A5B82DEC316331C12DC4C9DF59FB1FB44564185281D2C
$reduced
being only 53 characters long, causes an error, because openssl expects 64 chars:
# DER (ASN.1) as required by openssl
reduced_with_asn1_prefix="302E020100300506032B657004220420${reduced}"
reduced_in_der_format=$(printf "$reduced_with_asn1_prefix" | xxd -r -ps)
public=$(echo $reduced_in_der_format | openssl pkey -inform der -text)
# => ERROR "Could not read key"
I tried to prefix $reduced
with zeroes, suffix it with zeroes, as well as invert it for reverse endianness before doing so.
The result never matches the expected public key 0f3b913371411b27e646b537e888f685bf929ea7aab93c950ed84433f064480d.
Am I missing steps or doing them wrong?
EDIT: After adding ibase=16;
for bc the errors are gone, but the result is still different from the expected 0f3b91..
.
reduced=$(echo "obase=16;ibase=16; $secret % $l" | BC_LINE_LENGTH=0 bc)
bc
is off. You specified an output base of 16 (obase=16
) but not an input base (which defaults to 10). Try settingibase=16
.$reduced
is now 64, but the resulting public key is still wrong. Maybe some extra step missing?