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:

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_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)
  • 1
    Your usage of bc is off. You specified an output base of 16 (obase=16) but not an input base (which defaults to 10). Try setting ibase=16.
    – jtgrassie
    Commented Oct 12, 2023 at 22:54
  • This resolved the errors and the length of $reduced is now 64, but the resulting public key is still wrong. Maybe some extra step missing?
    – hokkjoy
    Commented Oct 14, 2023 at 14:38
  • Because you can't use openssl alone to get the public key from your private key. See the answers in the post you linked in your question.
    – jtgrassie
    Commented Oct 15, 2023 at 22:19


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.