libdecaf_curve25519 (libdecaf v3.0.0)

View Source

Ed25519 signatures, native streaming Ed25519ph, and X25519 key agreement.

keypair_random/0 and keypair_derive/1 return native keypair resources. keypair_extract_private_key/1 returns the 32-byte secret seed. In contrast, eddsa_keypair/0,1 returns {PublicKey, SigningKey}, where the 64-byte signing key is <<Seed/binary, PublicKey/binary>>.

Sign and verify a binary message using a native keypair:

Keypair = libdecaf_curve25519:keypair_random(),
PublicKey = libdecaf_curve25519:keypair_extract_public_key(Keypair),
Signature = libdecaf_curve25519:ed25519_keypair_sign(<<"message">>, Keypair),
true = libdecaf_curve25519:ed25519_verify(Signature, <<"message">>, PublicKey).

ed25519ph prehashes the original message using SHA-512. Do not prehash the message yourself. Streaming prehash signing keeps the keypair, context, and prehash in native resources and accepts iodata chunks:

{PublicKey, SigningKey} = libdecaf_curve25519:eddsa_keypair(),
S0 = libdecaf_curve25519:ed25519ph_sign_init(SigningKey, <<"example">>),
S1 = libdecaf_curve25519:ed25519ph_sign_update(S0, [<<"first ">>, <<"chunk">>]),
S2 = libdecaf_curve25519:ed25519ph_sign_update(S1, <<"second chunk">>),
Signature = libdecaf_curve25519:ed25519ph_sign_final(S2),
V0 = libdecaf_curve25519:ed25519ph_verify_init(Signature, PublicKey, <<"example">>),
V1 = libdecaf_curve25519:ed25519ph_verify_update(V0, <<"first chunksecond chunk">>),
true = libdecaf_curve25519:ed25519ph_verify_final(V1).

Use ed25519ph_keypair_sign_init/1,2 when you already have a native keypair. Both initializers produce the same signing state. Each update returns a new immutable state; finalization leaves its input reusable. Signing and verification states are distinct, and states from the other curve are rejected. Large updates yield to the scheduler, and message chunks are not retained after an update.

Contexts are binaries of at most 255 bytes and default to <<>> where supported. Pure Ed25519 has no context. Ed25519ctx uses domain separation even with an empty context, so its signatures are distinct from pure Ed25519 signatures.

X25519 uses 32-byte secret scalars and public keys. The scalar is the first argument to x25519/2; a rejected peer key returns error.

{AlicePublic, AliceSecret} = libdecaf_curve25519:x25519_keypair(),
{BobPublic, BobSecret} = libdecaf_curve25519:x25519_keypair(),
Shared = libdecaf_curve25519:x25519(AliceSecret, BobPublic),
Shared = libdecaf_curve25519:x25519(BobSecret, AlicePublic).

Signature encodings follow RFC 8032; key agreement follows RFC 7748.

Summary

Types

A signature context of at most 255 bytes. The empty context is <<>>.

An integer or a 32-byte little-endian X25519 coordinate.

An immutable native Ed25519ph signing state retaining its keypair and context.

An immutable native Ed25519ph verification state retaining its signature, public key, and context.

A public key paired with the encoded signing key <<Seed/binary, PublicKey/binary>>.

A native Ed25519 keypair resource, distinct from an encoded signing key.

An original message for one-shot signing or verification. Streaming updates accept iodata instead.

A 32-byte Ed25519 public key.

An integer or a 32-byte X25519 secret scalar.

A 64-byte signing key: the 32-byte secret seed followed by its matching public key.

A 32-byte secret seed used to derive an Ed25519 keypair.

A 64-byte Ed25519 signature encoding.

An X25519 public key paired with its secret scalar.

A 32-byte X25519 public key.

A 32-byte X25519 secret scalar, distinct from an Ed25519 secret seed.

A 32-byte X25519 shared secret.

Functions

Derive an X25519 public coordinate and return it as a little-endian integer. Integer scalars are encoded using their low 256 bits before the X25519 operation. Use x25519/1 for the binary-returning interface.

Compute X25519 with an integer or binary scalar and peer coordinate. Integers are encoded using their low 256 bits; the result is decoded as a little-endian integer. A rejected peer key raises {badmatch, error}. Use x25519/2 for a binary result or the atom error.

Sign a binary message using a native keypair and Ed25519. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

Sign a binary message using an encoded signing key and Ed25519. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

Verify a Ed25519 signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

Sign a binary message using a native keypair and Ed25519ctx. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

Sign a binary message using a native keypair and Ed25519ctx. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

Sign a binary message using an encoded signing key and Ed25519ctx. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

Sign a binary message using an encoded signing key and Ed25519ctx. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

Verify a Ed25519ctx signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

Verify a Ed25519ctx signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

Sign a binary message using a native keypair and Ed25519ph. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

Sign a binary message using a native keypair and Ed25519ph. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

Start native Ed25519ph signing using a keypair resource. The state retains the keypair, so the caller does not need to keep another reference. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context defaults to <<>>.

Start native Ed25519ph signing using a keypair resource. The state retains the keypair, so the caller does not need to keep another reference. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context must contain at most 255 bytes. For example

Sign a binary message using an encoded signing key and Ed25519ph. The NIF verifies that its seed and public key match; a mismatch raises an error. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

Sign a binary message using an encoded signing key and Ed25519ph. The NIF verifies that its seed and public key match; a mismatch raises an error. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

Sign the accumulated message with the retained keypair and context. The result matches ed25519ph_keypair_sign/3 for the same message, keypair, and context. Finalization leaves the state reusable and produces the same signature when repeated; it does not sign a caller-supplied digest.

Start native Ed25519ph signing using <<Seed/binary, PublicKey/binary>>. The NIF validates that both parts match and creates a retained native keypair; a mismatch raises an error. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context defaults to <<>>.

Start native Ed25519ph signing using <<Seed/binary, PublicKey/binary>>. The NIF validates that both parts match and creates a retained native keypair; a mismatch raises an error. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context must contain at most 255 bytes. For example

Prehash another chunk of the original message and return the next signing state. Both signing initializers use this function. The input state is unchanged, so it can be reused or branched. Large inputs yield; the chunk is released after the update.

Verify a Ed25519ph signature over a binary message. Return false for a correctly sized signature that does not verify. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

Verify a Ed25519ph signature over a binary message. Return false for a correctly sized signature that does not verify. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

Verify the accumulated message against the retained signature, public key, and context. Return false if verification fails. The state remains reusable, so repeated finalization returns the same result.

Start native Ed25519ph verification, retaining the signature and public key. The signature and public key must have 64 and 32 bytes respectively. Cryptographic verification happens in ed25519ph_verify_final/1. The context defaults to <<>>.

Start native Ed25519ph verification, retaining the signature and public key. The signature and public key must have 64 and 32 bytes respectively. Cryptographic verification happens in ed25519ph_verify_final/1. The context must match the signing context and contain at most 255 bytes.

Prehash another chunk of the original message and return the next verification state. The input state is unchanged. Large updates yield; a signing state or state from another algorithm is rejected.

Generate a random encoded keypair {PublicKey, <<Seed/binary, PublicKey/binary>>}. Use the second element with ed25519_sign/2 or ed25519ph_sign_init/1.

Derive an encoded keypair from a 32-byte secret seed. The returned signing key is the seed followed by its public key.

Convert an encoded Ed25519 keypair to a X25519 keypair. The supplied public key must match the public-key bytes in the signing key; the converted public and private parts must also agree.

Convert a Ed25519 public-key encoding to a X25519 public key. This conversion alone does not establish ownership of the corresponding secret key.

Derive the Ed25519 public key from a secret seed.

Derive an X25519 keypair from an Ed25519 secret seed. This applies the upstream private-key conversion before deriving the X25519 public key.

Convert a 32-byte Ed25519 secret seed to a 32-byte X25519 secret scalar.

Extract the public-key bytes from an encoded signing key. This only splits the encoding; it does not check that the seed and public key match.

Extract the secret-seed bytes from an encoded signing key. This only splits the encoding; it does not validate the public-key bytes.

Convert an encoded Ed25519 signing key to a X25519 keypair. Raise {badarg, [SigningKey]} if the converted public key differs from the public key derived from the converted seed.

Derive a native Ed25519 keypair from a 32-byte secret seed. The resource retains the seed and its derived public key.

Extract the 32-byte secret seed from a native keypair. This returns the seed alone, rather than the encoded seed/public key signing key.

Extract the 32-byte public key from a native Ed25519 keypair.

Generate a native Ed25519 keypair using crypto:strong_rand_bytes/1. Use this resource with ed25519_keypair_sign/2 or ed25519ph_keypair_sign_init/1.

Derive a 32-byte X25519 public key from a secret scalar. The scalar is clamped by the native X25519 operation.

Compute an X25519 shared secret with the secret scalar first and peer public key second. Return error when the native operation rejects a peer key, including low-order inputs producing an all-zero shared secret. Both keys must have 32 bytes.

Generate a random X25519 keypair {PublicKey, SecretScalar}. The secret scalar contains 32 random bytes from crypto:strong_rand_bytes/1.

Derive an X25519 keypair {PublicKey, SecretScalar} from the supplied scalar. The returned scalar bytes are the supplied bytes; clamping happens inside X25519.

Types

context()

-type context() :: binary().

A signature context of at most 255 bytes. The empty context is <<>>.

coordinate()

-type coordinate() :: integer() | x25519_public_key().

An integer or a 32-byte little-endian X25519 coordinate.

ed25519ph_sign_state()

-type ed25519ph_sign_state() :: libdecaf_nif:ed25519ph_sign_state().

An immutable native Ed25519ph signing state retaining its keypair and context.

ed25519ph_verify_state()

-type ed25519ph_verify_state() :: libdecaf_nif:ed25519ph_verify_state().

An immutable native Ed25519ph verification state retaining its signature, public key, and context.

eddsa_keypair()

-type eddsa_keypair() :: {public_key(), secret_key()}.

A public key paired with the encoded signing key <<Seed/binary, PublicKey/binary>>.

keypair()

-type keypair() :: libdecaf_nif:ed25519_keypair().

A native Ed25519 keypair resource, distinct from an encoded signing key.

message()

-type message() :: binary().

An original message for one-shot signing or verification. Streaming updates accept iodata instead.

public_key()

-type public_key() :: libdecaf_nif:ed25519_public_key().

A 32-byte Ed25519 public key.

scalar()

-type scalar() :: integer() | x25519_secret_key().

An integer or a 32-byte X25519 secret scalar.

secret_key()

-type secret_key() :: libdecaf_nif:ed25519_signing_key().

A 64-byte signing key: the 32-byte secret seed followed by its matching public key.

seed()

-type seed() :: libdecaf_nif:ed25519_secret_key().

A 32-byte secret seed used to derive an Ed25519 keypair.

signature()

-type signature() :: libdecaf_nif:ed25519_signature().

A 64-byte Ed25519 signature encoding.

x25519_keypair()

-type x25519_keypair() :: {x25519_public_key(), x25519_secret_key()}.

An X25519 public key paired with its secret scalar.

x25519_public_key()

-type x25519_public_key() :: libdecaf_nif:x25519_public_key().

A 32-byte X25519 public key.

x25519_secret_key()

-type x25519_secret_key() :: libdecaf_nif:x25519_scalar().

A 32-byte X25519 secret scalar, distinct from an Ed25519 secret seed.

x25519_shared_secret()

-type x25519_shared_secret() :: libdecaf_nif:x25519_shared_secret().

A 32-byte X25519 shared secret.

Functions

curve25519(Scalar)

-spec curve25519(Scalar) -> Coordinate when Scalar :: scalar(), Coordinate :: non_neg_integer().

Derive an X25519 public coordinate and return it as a little-endian integer. Integer scalars are encoded using their low 256 bits before the X25519 operation. Use x25519/1 for the binary-returning interface.

curve25519(Scalar, Coordinate)

-spec curve25519(Scalar, Coordinate) -> SharedCoordinate
                    when
                        Scalar :: scalar(),
                        Coordinate :: coordinate(),
                        SharedCoordinate :: non_neg_integer().

Compute X25519 with an integer or binary scalar and peer coordinate. Integers are encoded using their low 256 bits; the result is decoded as a little-endian integer. A rejected peer key raises {badmatch, error}. Use x25519/2 for a binary result or the atom error.

ed25519_keypair_sign(Message, Keypair)

-spec ed25519_keypair_sign(Message, Keypair) -> Signature
                              when Message :: message(), Keypair :: keypair(), Signature :: signature().

Sign a binary message using a native keypair and Ed25519. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

ed25519_sign(Message, SigningKey)

-spec ed25519_sign(Message, SigningKey) -> Signature
                      when Message :: message(), SigningKey :: secret_key(), Signature :: signature().

Sign a binary message using an encoded signing key and Ed25519. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

ed25519_verify(Signature, Message, PublicKey)

-spec ed25519_verify(Signature, Message, PublicKey) -> Valid
                        when
                            Signature :: signature(),
                            Message :: message(),
                            PublicKey :: public_key(),
                            Valid :: boolean().

Verify a Ed25519 signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. This is pure Ed25519, without a context or Ed25519ctx domain separation.

ed25519ctx_keypair_sign(Message, Keypair)

-spec ed25519ctx_keypair_sign(Message, Keypair) -> Signature
                                 when
                                     Message :: message(),
                                     Keypair :: keypair(),
                                     Signature :: signature().

Sign a binary message using a native keypair and Ed25519ctx. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ctx_keypair_sign(Message, Keypair, Context)

-spec ed25519ctx_keypair_sign(Message, Keypair, Context) -> Signature
                                 when
                                     Message :: message(),
                                     Keypair :: keypair(),
                                     Context :: context(),
                                     Signature :: signature().

Sign a binary message using a native keypair and Ed25519ctx. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

ed25519ctx_sign(Message, SigningKey)

-spec ed25519ctx_sign(Message, SigningKey) -> Signature
                         when Message :: message(), SigningKey :: secret_key(), Signature :: signature().

Sign a binary message using an encoded signing key and Ed25519ctx. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ctx_sign(Message, SigningKey, Context)

-spec ed25519ctx_sign(Message, SigningKey, Context) -> Signature
                         when
                             Message :: message(),
                             SigningKey :: secret_key(),
                             Context :: context(),
                             Signature :: signature().

Sign a binary message using an encoded signing key and Ed25519ctx. The NIF verifies that its seed and public key match; a mismatch raises an error. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

ed25519ctx_verify(Signature, Message, PublicKey)

-spec ed25519ctx_verify(Signature, Message, PublicKey) -> Valid
                           when
                               Signature :: signature(),
                               Message :: message(),
                               PublicKey :: public_key(),
                               Valid :: boolean().

Verify a Ed25519ctx signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ctx_verify(Signature, Message, PublicKey, Context)

-spec ed25519ctx_verify(Signature, Message, PublicKey, Context) -> Valid
                           when
                               Signature :: signature(),
                               Message :: message(),
                               PublicKey :: public_key(),
                               Context :: context(),
                               Valid :: boolean().

Verify a Ed25519ctx signature over a binary message. Return false for a correctly sized signature that does not verify. The message is signed directly without the prehash variant. The context must be a binary of at most 255 bytes and must match between signing and verification. Even <<>> selects Ed25519ctx domain separation, rather than pure Ed25519.

ed25519ph_keypair_sign(Message, Keypair)

-spec ed25519ph_keypair_sign(Message, Keypair) -> Signature
                                when
                                    Message :: message(), Keypair :: keypair(), Signature :: signature().

Sign a binary message using a native keypair and Ed25519ph. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ph_keypair_sign(Message, Keypair, Context)

-spec ed25519ph_keypair_sign(Message, Keypair, Context) -> Signature
                                when
                                    Message :: message(),
                                    Keypair :: keypair(),
                                    Context :: context(),
                                    Signature :: signature().

Sign a binary message using a native keypair and Ed25519ph. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

ed25519ph_keypair_sign_init(Keypair)

-spec ed25519ph_keypair_sign_init(Keypair) -> State
                                     when Keypair :: keypair(), State :: ed25519ph_sign_state().

Start native Ed25519ph signing using a keypair resource. The state retains the keypair, so the caller does not need to keep another reference. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context defaults to <<>>.

ed25519ph_keypair_sign_init(Keypair, Context)

-spec ed25519ph_keypair_sign_init(Keypair, Context) -> State
                                     when
                                         Keypair :: keypair(),
                                         Context :: context(),
                                         State :: ed25519ph_sign_state().

Start native Ed25519ph signing using a keypair resource. The state retains the keypair, so the caller does not need to keep another reference. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context must contain at most 255 bytes. For example:

Keypair = libdecaf_curve25519:keypair_random(),
S0 = libdecaf_curve25519:ed25519ph_keypair_sign_init(Keypair, <<"example">>),
S1 = libdecaf_curve25519:ed25519ph_sign_update(S0, [<<"hello ">>, <<"world">>]),
Signature = libdecaf_curve25519:ed25519ph_sign_final(S1).

ed25519ph_sign(Message, SigningKey)

-spec ed25519ph_sign(Message, SigningKey) -> Signature
                        when Message :: message(), SigningKey :: secret_key(), Signature :: signature().

Sign a binary message using an encoded signing key and Ed25519ph. The NIF verifies that its seed and public key match; a mismatch raises an error. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ph_sign(Message, SigningKey, Context)

-spec ed25519ph_sign(Message, SigningKey, Context) -> Signature
                        when
                            Message :: message(),
                            SigningKey :: secret_key(),
                            Context :: context(),
                            Signature :: signature().

Sign a binary message using an encoded signing key and Ed25519ph. The NIF verifies that its seed and public key match; a mismatch raises an error. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

ed25519ph_sign_final(State)

-spec ed25519ph_sign_final(State) -> Signature
                              when State :: ed25519ph_sign_state(), Signature :: signature().

Sign the accumulated message with the retained keypair and context. The result matches ed25519ph_keypair_sign/3 for the same message, keypair, and context. Finalization leaves the state reusable and produces the same signature when repeated; it does not sign a caller-supplied digest.

ed25519ph_sign_init(SigningKey)

-spec ed25519ph_sign_init(SigningKey) -> State
                             when SigningKey :: secret_key(), State :: ed25519ph_sign_state().

Start native Ed25519ph signing using <<Seed/binary, PublicKey/binary>>. The NIF validates that both parts match and creates a retained native keypair; a mismatch raises an error. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context defaults to <<>>.

ed25519ph_sign_init(SigningKey, Context)

-spec ed25519ph_sign_init(SigningKey, Context) -> State
                             when
                                 SigningKey :: secret_key(),
                                 Context :: context(),
                                 State :: ed25519ph_sign_state().

Start native Ed25519ph signing using <<Seed/binary, PublicKey/binary>>. The NIF validates that both parts match and creates a retained native keypair; a mismatch raises an error. Continue with ed25519ph_sign_update/2 and ed25519ph_sign_final/1. The context must contain at most 255 bytes. For example:

{_PublicKey, SigningKey} = libdecaf_curve25519:eddsa_keypair(),
S0 = libdecaf_curve25519:ed25519ph_sign_init(SigningKey, <<"example">>),
S1 = libdecaf_curve25519:ed25519ph_sign_update(S0, [<<"hello ">>, <<"world">>]),
Signature = libdecaf_curve25519:ed25519ph_sign_final(S1).

ed25519ph_sign_update(State, Input)

-spec ed25519ph_sign_update(State, Input) -> NextState
                               when
                                   State :: ed25519ph_sign_state(),
                                   Input :: iodata(),
                                   NextState :: ed25519ph_sign_state().

Prehash another chunk of the original message and return the next signing state. Both signing initializers use this function. The input state is unchanged, so it can be reused or branched. Large inputs yield; the chunk is released after the update.

ed25519ph_verify(Signature, Message, PublicKey)

-spec ed25519ph_verify(Signature, Message, PublicKey) -> Valid
                          when
                              Signature :: signature(),
                              Message :: message(),
                              PublicKey :: public_key(),
                              Valid :: boolean().

Verify a Ed25519ph signature over a binary message. Return false for a correctly sized signature that does not verify. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. Use an empty context, equivalent to passing <<>> to the next arity.

ed25519ph_verify(Signature, Message, PublicKey, Context)

-spec ed25519ph_verify(Signature, Message, PublicKey, Context) -> Valid
                          when
                              Signature :: signature(),
                              Message :: message(),
                              PublicKey :: public_key(),
                              Context :: context(),
                              Valid :: boolean().

Verify a Ed25519ph signature over a binary message. Return false for a correctly sized signature that does not verify. Pass the original message; Ed25519ph computes its SHA-512 prehash internally. The context must be a binary of at most 255 bytes and must match between signing and verification.

ed25519ph_verify_final(State)

-spec ed25519ph_verify_final(State) -> Valid when State :: ed25519ph_verify_state(), Valid :: boolean().

Verify the accumulated message against the retained signature, public key, and context. Return false if verification fails. The state remains reusable, so repeated finalization returns the same result.

ed25519ph_verify_init(Signature, PublicKey)

-spec ed25519ph_verify_init(Signature, PublicKey) -> State
                               when
                                   Signature :: signature(),
                                   PublicKey :: public_key(),
                                   State :: ed25519ph_verify_state().

Start native Ed25519ph verification, retaining the signature and public key. The signature and public key must have 64 and 32 bytes respectively. Cryptographic verification happens in ed25519ph_verify_final/1. The context defaults to <<>>.

ed25519ph_verify_init(Signature, PublicKey, Context)

-spec ed25519ph_verify_init(Signature, PublicKey, Context) -> State
                               when
                                   Signature :: signature(),
                                   PublicKey :: public_key(),
                                   Context :: context(),
                                   State :: ed25519ph_verify_state().

Start native Ed25519ph verification, retaining the signature and public key. The signature and public key must have 64 and 32 bytes respectively. Cryptographic verification happens in ed25519ph_verify_final/1. The context must match the signing context and contain at most 255 bytes.

Keypair = libdecaf_curve25519:keypair_random(),
PublicKey = libdecaf_curve25519:keypair_extract_public_key(Keypair),
Signature = libdecaf_curve25519:ed25519ph_keypair_sign(<<"hello world">>, Keypair, <<"example">>),
V0 = libdecaf_curve25519:ed25519ph_verify_init(Signature, PublicKey, <<"example">>),
V1 = libdecaf_curve25519:ed25519ph_verify_update(V0, [<<"hello ">>, <<"world">>]),
true = libdecaf_curve25519:ed25519ph_verify_final(V1).

ed25519ph_verify_update(State, Input)

-spec ed25519ph_verify_update(State, Input) -> NextState
                                 when
                                     State :: ed25519ph_verify_state(),
                                     Input :: iodata(),
                                     NextState :: ed25519ph_verify_state().

Prehash another chunk of the original message and return the next verification state. The input state is unchanged. Large updates yield; a signing state or state from another algorithm is rejected.

eddsa_keypair()

-spec eddsa_keypair() -> Keypair when Keypair :: eddsa_keypair().

Generate a random encoded keypair {PublicKey, <<Seed/binary, PublicKey/binary>>}. Use the second element with ed25519_sign/2 or ed25519ph_sign_init/1.

eddsa_keypair(Seed)

-spec eddsa_keypair(Seed) -> Keypair when Seed :: seed(), Keypair :: eddsa_keypair().

Derive an encoded keypair from a 32-byte secret seed. The returned signing key is the seed followed by its public key.

eddsa_keypair_to_x25519_keypair(Keypair)

-spec eddsa_keypair_to_x25519_keypair(Keypair) -> KeypairX
                                         when Keypair :: eddsa_keypair(), KeypairX :: x25519_keypair().

Convert an encoded Ed25519 keypair to a X25519 keypair. The supplied public key must match the public-key bytes in the signing key; the converted public and private parts must also agree.

eddsa_pk_to_x25519_pk(PublicKey)

-spec eddsa_pk_to_x25519_pk(PublicKey) -> PublicKeyX
                               when PublicKey :: public_key(), PublicKeyX :: x25519_public_key().

Convert a Ed25519 public-key encoding to a X25519 public key. This conversion alone does not establish ownership of the corresponding secret key.

eddsa_secret_to_pk(Seed)

-spec eddsa_secret_to_pk(Seed) -> PublicKey when Seed :: seed(), PublicKey :: public_key().

Derive the Ed25519 public key from a secret seed.

eddsa_secret_to_x25519_keypair(Seed)

-spec eddsa_secret_to_x25519_keypair(Seed) -> KeypairX when Seed :: seed(), KeypairX :: x25519_keypair().

Derive an X25519 keypair from an Ed25519 secret seed. This applies the upstream private-key conversion before deriving the X25519 public key.

eddsa_secret_to_x25519_secret(Seed)

-spec eddsa_secret_to_x25519_secret(Seed) -> SecretX when Seed :: seed(), SecretX :: x25519_secret_key().

Convert a 32-byte Ed25519 secret seed to a 32-byte X25519 secret scalar.

eddsa_sk_to_pk(SigningKey)

-spec eddsa_sk_to_pk(SigningKey) -> PublicKey when SigningKey :: secret_key(), PublicKey :: public_key().

Extract the public-key bytes from an encoded signing key. This only splits the encoding; it does not check that the seed and public key match.

eddsa_sk_to_secret(SigningKey)

-spec eddsa_sk_to_secret(SigningKey) -> Seed when SigningKey :: secret_key(), Seed :: seed().

Extract the secret-seed bytes from an encoded signing key. This only splits the encoding; it does not validate the public-key bytes.

eddsa_sk_to_x25519_keypair(SigningKey)

-spec eddsa_sk_to_x25519_keypair(SigningKey) -> KeypairX
                                    when SigningKey :: secret_key(), KeypairX :: x25519_keypair().

Convert an encoded Ed25519 signing key to a X25519 keypair. Raise {badarg, [SigningKey]} if the converted public key differs from the public key derived from the converted seed.

keypair_derive(Seed)

-spec keypair_derive(Seed) -> Keypair when Seed :: seed(), Keypair :: keypair().

Derive a native Ed25519 keypair from a 32-byte secret seed. The resource retains the seed and its derived public key.

keypair_extract_private_key(Keypair)

-spec keypair_extract_private_key(Keypair) -> Seed when Keypair :: keypair(), Seed :: seed().

Extract the 32-byte secret seed from a native keypair. This returns the seed alone, rather than the encoded seed/public key signing key.

keypair_extract_public_key(Keypair)

-spec keypair_extract_public_key(Keypair) -> PublicKey
                                    when Keypair :: keypair(), PublicKey :: public_key().

Extract the 32-byte public key from a native Ed25519 keypair.

keypair_random()

-spec keypair_random() -> Keypair when Keypair :: keypair().

Generate a native Ed25519 keypair using crypto:strong_rand_bytes/1. Use this resource with ed25519_keypair_sign/2 or ed25519ph_keypair_sign_init/1.

x25519(Secret)

-spec x25519(Secret) -> PublicKey when Secret :: x25519_secret_key(), PublicKey :: x25519_public_key().

Derive a 32-byte X25519 public key from a secret scalar. The scalar is clamped by the native X25519 operation.

x25519(Secret, PeerPublicKey)

-spec x25519(Secret, PeerPublicKey) -> SharedSecret
                when
                    Secret :: x25519_secret_key(),
                    PeerPublicKey :: x25519_public_key(),
                    SharedSecret :: x25519_shared_secret() | error.

Compute an X25519 shared secret with the secret scalar first and peer public key second. Return error when the native operation rejects a peer key, including low-order inputs producing an all-zero shared secret. Both keys must have 32 bytes.

x25519_keypair()

-spec x25519_keypair() -> Keypair when Keypair :: x25519_keypair().

Generate a random X25519 keypair {PublicKey, SecretScalar}. The secret scalar contains 32 random bytes from crypto:strong_rand_bytes/1.

x25519_keypair(Secret)

-spec x25519_keypair(Secret) -> Keypair when Secret :: x25519_secret_key(), Keypair :: x25519_keypair().

Derive an X25519 keypair {PublicKey, SecretScalar} from the supplied scalar. The returned scalar bytes are the supplied bytes; clamping happens inside X25519.