ENHANCED: Use crrl for Ed25519 signing and signature verification.
The main motivation for this change is the introduction of the newly available predicate ed25519_seed_keypair/2, allowing to generate a key pair from a given seed. In this way, a key pair can be dynamically generated from (for example) a password, using crypto_password_hash/3 in combination with crypto_data_hkdf/4 to generate the seed. The advantage of this method is that the private key need not be stored at all anywhere. It is not possible to add a corresponding feature to ring, since it is closed as "not planned": https://github.com/briansmith/ring/issues/1003 I also used this opportunity to move more of the logic to Prolog. We now have total control of the key pair representation, and I also changed the representation to conform to the PKCS#8 v2 standard, something that only later ring versions do, while still being backwards compatible with tools that produce a wrong representation including earlier ring versions. Another great advantage we get from this change is that the Ed25519 predicates now also run on the 32-bit and WASM versions of Scryer.
This commit is contained in:
@@ -511,18 +511,12 @@ enum SystemClauseType {
|
|||||||
#[cfg(feature = "crypto-full")]
|
#[cfg(feature = "crypto-full")]
|
||||||
#[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
|
#[strum_discriminants(strum(props(Arity = "6", Name = "$crypto_data_decrypt")))]
|
||||||
CryptoDataDecrypt,
|
CryptoDataDecrypt,
|
||||||
#[cfg(feature = "crypto-full")]
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign_raw")))]
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_sign")))]
|
Ed25519SignRaw,
|
||||||
Ed25519Sign,
|
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify_raw")))]
|
||||||
#[cfg(feature = "crypto-full")]
|
Ed25519VerifyRaw,
|
||||||
#[strum_discriminants(strum(props(Arity = "4", Name = "$ed25519_verify")))]
|
#[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_seed_to_public_key")))]
|
||||||
Ed25519Verify,
|
Ed25519SeedToPublicKey,
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
#[strum_discriminants(strum(props(Arity = "1", Name = "$ed25519_new_keypair")))]
|
|
||||||
Ed25519NewKeyPair,
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "$ed25519_keypair_public_key")))]
|
|
||||||
Ed25519KeyPairPublicKey,
|
|
||||||
#[strum_discriminants(strum(props(Arity = "2", Name = "$first_non_octet")))]
|
#[strum_discriminants(strum(props(Arity = "2", Name = "$first_non_octet")))]
|
||||||
FirstNonOctet,
|
FirstNonOctet,
|
||||||
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_html")))]
|
#[strum_discriminants(strum(props(Arity = "3", Name = "$load_html")))]
|
||||||
@@ -1874,18 +1868,17 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::CallFlushTermQueue |
|
&Instruction::CallFlushTermQueue |
|
||||||
&Instruction::CallRemoveModuleExports |
|
&Instruction::CallRemoveModuleExports |
|
||||||
&Instruction::CallAddNonCountedBacktracking |
|
&Instruction::CallAddNonCountedBacktracking |
|
||||||
&Instruction::CallPopCount => {
|
&Instruction::CallPopCount |
|
||||||
|
&Instruction::CallEd25519SignRaw |
|
||||||
|
&Instruction::CallEd25519VerifyRaw |
|
||||||
|
&Instruction::CallEd25519SeedToPublicKey => {
|
||||||
let (name, arity) = self.to_name_and_arity();
|
let (name, arity) = self.to_name_and_arity();
|
||||||
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
#[cfg(feature = "crypto-full")]
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::CallCryptoDataEncrypt |
|
&Instruction::CallCryptoDataEncrypt |
|
||||||
&Instruction::CallCryptoDataDecrypt |
|
&Instruction::CallCryptoDataDecrypt => {
|
||||||
&Instruction::CallEd25519Sign |
|
|
||||||
&Instruction::CallEd25519Verify |
|
|
||||||
&Instruction::CallEd25519NewKeyPair |
|
|
||||||
&Instruction::CallEd25519KeyPairPublicKey => {
|
|
||||||
let (name, arity) = self.to_name_and_arity();
|
let (name, arity) = self.to_name_and_arity();
|
||||||
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
functor!(atom!("call"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
@@ -2110,18 +2103,17 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
&Instruction::ExecuteFlushTermQueue |
|
&Instruction::ExecuteFlushTermQueue |
|
||||||
&Instruction::ExecuteRemoveModuleExports |
|
&Instruction::ExecuteRemoveModuleExports |
|
||||||
&Instruction::ExecuteAddNonCountedBacktracking |
|
&Instruction::ExecuteAddNonCountedBacktracking |
|
||||||
&Instruction::ExecutePopCount => {
|
&Instruction::ExecutePopCount |
|
||||||
|
&Instruction::ExecuteEd25519SignRaw |
|
||||||
|
&Instruction::ExecuteEd25519VerifyRaw |
|
||||||
|
&Instruction::ExecuteEd25519SeedToPublicKey => {
|
||||||
let (name, arity) = self.to_name_and_arity();
|
let (name, arity) = self.to_name_and_arity();
|
||||||
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
#[cfg(feature = "crypto-full")]
|
#[cfg(feature = "crypto-full")]
|
||||||
&Instruction::ExecuteCryptoDataEncrypt |
|
&Instruction::ExecuteCryptoDataEncrypt |
|
||||||
&Instruction::ExecuteCryptoDataDecrypt |
|
&Instruction::ExecuteCryptoDataDecrypt => {
|
||||||
&Instruction::ExecuteEd25519Sign |
|
|
||||||
&Instruction::ExecuteEd25519Verify |
|
|
||||||
&Instruction::ExecuteEd25519NewKeyPair |
|
|
||||||
&Instruction::ExecuteEd25519KeyPairPublicKey => {
|
|
||||||
let (name, arity) = self.to_name_and_arity();
|
let (name, arity) = self.to_name_and_arity();
|
||||||
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
functor!(atom!("execute"), [atom(name), fixnum(arity)])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
crypto_password_hash/3, % +Password, -Hash, +Options
|
crypto_password_hash/3, % +Password, -Hash, +Options
|
||||||
crypto_data_encrypt/6, % +PlainText, +Algorithm, +Key, +IV, -CipherText, +Options
|
crypto_data_encrypt/6, % +PlainText, +Algorithm, +Key, +IV, -CipherText, +Options
|
||||||
crypto_data_decrypt/6, % +CipherText, +Algorithm, +Key, +IV, -PlainText, +Options
|
crypto_data_decrypt/6, % +CipherText, +Algorithm, +Key, +IV, -PlainText, +Options
|
||||||
|
ed25519_seed_keypair/2, % +Seed, -KeyPair
|
||||||
ed25519_new_keypair/1, % -KeyPair
|
ed25519_new_keypair/1, % -KeyPair
|
||||||
ed25519_keypair_public_key/2, % +KeyPair, +PublicKey
|
ed25519_keypair_public_key/2, % +KeyPair, +PublicKey
|
||||||
ed25519_sign/4, % +KeyPair, +Data, -Signature, +Options
|
ed25519_sign/4, % +KeyPair, +Data, -Signature, +Options
|
||||||
@@ -612,6 +613,34 @@ encoding_chars(utf8, Cs, Cs) :-
|
|||||||
===============================
|
===============================
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
%% ed25519_seed_keypair(+Seed, -Pair)
|
||||||
|
%
|
||||||
|
% Use Seed to deterministically generate an Ed25519 key pair Pair, a
|
||||||
|
% list of characters. Seed must be a list of 32 bytes. It can be
|
||||||
|
% chosen at random (using for example `crypto_n_random_bytes/2`) or
|
||||||
|
% derived from input keying material (IKM) using for example
|
||||||
|
% `crypto_data_hkdf/4`. The pair contains the private key and must be
|
||||||
|
% kept absolutely secret. Pair can be used for signing. Its public
|
||||||
|
% key can be obtained with `ed25519_keypair_public_key/2`.
|
||||||
|
|
||||||
|
ed25519_seed_keypair(Seed, Pair) :-
|
||||||
|
must_be_bytes(Seed, ed25519_keypair_from_seed/2),
|
||||||
|
length(Seed, 32),
|
||||||
|
'$ed25519_seed_to_public_key'(Seed, Public),
|
||||||
|
maplist(char_code, Public, PublicBytes),
|
||||||
|
phrase(([0x30,81], % a sequence of 81 bytes follows
|
||||||
|
[2,1], % the integer 1 denoting version 2 (awesome design!)
|
||||||
|
[1], % the public key is also present
|
||||||
|
[48,5], % an element of 5 bytes follows
|
||||||
|
[6,3,43,101,112], % OID of Ed25519
|
||||||
|
[4,34], % an octet string of 34 bytes follows
|
||||||
|
[4,32], % an octet string of 32 bytes follows
|
||||||
|
seq(Seed), % the seed is the private key
|
||||||
|
[129,33],
|
||||||
|
[0], % 32 bytes is divisible by 8
|
||||||
|
seq(PublicBytes)), ASN1),
|
||||||
|
maplist(char_code, Pair, ASN1).
|
||||||
|
|
||||||
%% ed25519_new_keypair(-Pair)
|
%% ed25519_new_keypair(-Pair)
|
||||||
%
|
%
|
||||||
% Yields a new Ed25519 key pair Pair, a list of characters. The
|
% Yields a new Ed25519 key pair Pair, a list of characters. The
|
||||||
@@ -620,7 +649,8 @@ encoding_chars(utf8, Cs, Cs) :-
|
|||||||
% with `ed25519_keypair_public_key/2`.
|
% with `ed25519_keypair_public_key/2`.
|
||||||
|
|
||||||
ed25519_new_keypair(Pair) :-
|
ed25519_new_keypair(Pair) :-
|
||||||
'$ed25519_new_keypair'(Pair).
|
crypto_n_random_bytes(32, Bytes),
|
||||||
|
ed25519_seed_keypair(Bytes, Pair).
|
||||||
|
|
||||||
%% ed25519_keypair_public_key(+Pair, -PublicKey)
|
%% ed25519_keypair_public_key(+Pair, -PublicKey)
|
||||||
%
|
%
|
||||||
@@ -629,8 +659,11 @@ ed25519_new_keypair(Pair) :-
|
|||||||
% The public key is represented as a list of characters.
|
% The public key is represented as a list of characters.
|
||||||
|
|
||||||
ed25519_keypair_public_key(Pair, PublicKey) :-
|
ed25519_keypair_public_key(Pair, PublicKey) :-
|
||||||
must_be_octet_chars(Pair, ed25519_keypair_public_key),
|
must_be_octet_chars(Pair, ed25519_keypair_public_key/2),
|
||||||
'$ed25519_keypair_public_key'(Pair, PublicKey).
|
reverse(Pair, RPs),
|
||||||
|
length(RPublicKey, 32),
|
||||||
|
phrase((seq(RPublicKey),...), RPs),
|
||||||
|
reverse(RPublicKey, PublicKey).
|
||||||
|
|
||||||
%% ed25519_sign(+Key, +Data, -Signature, +Options)
|
%% ed25519_sign(+Key, +Data, -Signature, +Options)
|
||||||
%
|
%
|
||||||
@@ -638,10 +671,14 @@ ed25519_keypair_public_key(Pair, PublicKey) :-
|
|||||||
% PKCS#8 v2 format as generated by `ed25519_new_keypair/1`. Sign Data
|
% PKCS#8 v2 format as generated by `ed25519_new_keypair/1`. Sign Data
|
||||||
% with Key, yielding Signature as a list of hexadecimal characters.
|
% with Key, yielding Signature as a list of hexadecimal characters.
|
||||||
|
|
||||||
ed25519_sign(Key, Data0, Signature, Options) :-
|
ed25519_sign(KeyPair, Data0, Signature, Options) :-
|
||||||
must_be_octet_chars(Key, ed25519_sign),
|
must_be_octet_chars(KeyPair, ed25519_sign/4),
|
||||||
|
length(Prefix, 16),
|
||||||
|
length(PrivateKeyChars, 32),
|
||||||
|
phrase((seq(Prefix),seq(PrivateKeyChars),...), KeyPair),
|
||||||
|
maplist(char_code, PrivateKeyChars, PrivateKey),
|
||||||
options_data_chars(Options, Data0, Data, Encoding),
|
options_data_chars(Options, Data0, Data, Encoding),
|
||||||
'$ed25519_sign'(Key, Data, Encoding, Signature0),
|
'$ed25519_sign_raw'(PrivateKey, Data, Encoding, Signature0),
|
||||||
hex_bytes(Signature, Signature0).
|
hex_bytes(Signature, Signature0).
|
||||||
|
|
||||||
%% ed25519_verify(+Key, +Data, +Signature, +Options)
|
%% ed25519_verify(+Key, +Data, +Signature, +Options)
|
||||||
@@ -658,10 +695,10 @@ ed25519_sign(Key, Data0, Signature, Options) :-
|
|||||||
% which treats Data as a list of raw bytes.
|
% which treats Data as a list of raw bytes.
|
||||||
|
|
||||||
ed25519_verify(Key, Data0, Signature0, Options) :-
|
ed25519_verify(Key, Data0, Signature0, Options) :-
|
||||||
must_be_octet_chars(Key, ed25519_verify),
|
must_be_octet_chars(Key, ed25519_verify/4),
|
||||||
options_data_chars(Options, Data0, Data, Encoding),
|
options_data_chars(Options, Data0, Data, Encoding),
|
||||||
hex_bytes(Signature0, Signature),
|
hex_bytes(Signature0, Signature),
|
||||||
'$ed25519_verify'(Key, Data, Encoding, Signature).
|
'$ed25519_verify_raw'(Key, Data, Encoding, Signature).
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
X25519: ECDH key exchange over Curve25519
|
X25519: ECDH key exchange over Curve25519
|
||||||
|
|||||||
@@ -4491,44 +4491,28 @@ impl Machine {
|
|||||||
self.crypto_curve_scalar_mult();
|
self.crypto_curve_scalar_mult();
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::CallEd25519SignRaw => {
|
||||||
&Instruction::CallEd25519Sign => {
|
self.ed25519_sign_raw();
|
||||||
self.ed25519_sign();
|
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::ExecuteEd25519SignRaw => {
|
||||||
&Instruction::ExecuteEd25519Sign => {
|
self.ed25519_sign_raw();
|
||||||
self.ed25519_sign();
|
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::CallEd25519VerifyRaw => {
|
||||||
&Instruction::CallEd25519Verify => {
|
self.ed25519_verify_raw();
|
||||||
self.ed25519_verify();
|
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::ExecuteEd25519VerifyRaw => {
|
||||||
&Instruction::ExecuteEd25519Verify => {
|
self.ed25519_verify_raw();
|
||||||
self.ed25519_verify();
|
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::CallEd25519SeedToPublicKey => {
|
||||||
&Instruction::CallEd25519NewKeyPair => {
|
self.ed25519_seed_to_public_key();
|
||||||
self.ed25519_new_key_pair();
|
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
step_or_fail!(self, self.machine_st.p += 1);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "crypto-full")]
|
&Instruction::ExecuteEd25519SeedToPublicKey => {
|
||||||
&Instruction::ExecuteEd25519NewKeyPair => {
|
self.ed25519_seed_to_public_key();
|
||||||
self.ed25519_new_key_pair();
|
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
&Instruction::CallEd25519KeyPairPublicKey => {
|
|
||||||
self.ed25519_key_pair_public_key();
|
|
||||||
step_or_fail!(self, self.machine_st.p += 1);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
&Instruction::ExecuteEd25519KeyPairPublicKey => {
|
|
||||||
self.ed25519_key_pair_public_key();
|
|
||||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||||
}
|
}
|
||||||
&Instruction::CallCurve25519ScalarMult => {
|
&Instruction::CallCurve25519ScalarMult => {
|
||||||
|
|||||||
@@ -81,14 +81,11 @@ use ring::rand::{SecureRandom, SystemRandom};
|
|||||||
use ring::{digest, hkdf, pbkdf2};
|
use ring::{digest, hkdf, pbkdf2};
|
||||||
|
|
||||||
#[cfg(feature = "crypto-full")]
|
#[cfg(feature = "crypto-full")]
|
||||||
use ring::{
|
use ring::aead;
|
||||||
aead,
|
|
||||||
signature::{self, KeyPair},
|
|
||||||
};
|
|
||||||
use ripemd160::{Digest, Ripemd160};
|
use ripemd160::{Digest, Ripemd160};
|
||||||
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
|
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
|
||||||
|
|
||||||
use crrl::{secp256k1, x25519};
|
use crrl::{ed25519, secp256k1, x25519};
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use native_tls::{Identity, TlsAcceptor, TlsConnector};
|
use native_tls::{Identity, TlsAcceptor, TlsConnector};
|
||||||
@@ -7617,33 +7614,16 @@ impl Machine {
|
|||||||
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
|
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_new_key_pair(&mut self) {
|
pub(crate) fn ed25519_seed_to_public_key(&mut self) {
|
||||||
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(rng()).unwrap();
|
let stub_gen = || functor_stub(atom!("ed25519_seed_keypair"), 2);
|
||||||
let complete_string = self.u8s_to_string(pkcs8_bytes.as_ref());
|
let seed_bytes = self
|
||||||
|
.machine_st
|
||||||
|
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
|
||||||
|
|
||||||
unify!(
|
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
|
||||||
self.machine_st,
|
|
||||||
self.machine_st.registers[1],
|
|
||||||
complete_string
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "crypto-full")]
|
let complete_string = self.u8s_to_string(skey.public_key.encoded.as_ref());
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) fn ed25519_key_pair_public_key(&mut self) {
|
|
||||||
let bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
|
||||||
|
|
||||||
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&bytes) {
|
|
||||||
Ok(kp) => kp,
|
|
||||||
_ => {
|
|
||||||
self.machine_st.fail = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let complete_string = self.u8s_to_string(key_pair.public_key().as_ref());
|
|
||||||
|
|
||||||
unify!(
|
unify!(
|
||||||
self.machine_st,
|
self.machine_st,
|
||||||
@@ -7652,22 +7632,19 @@ impl Machine {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_sign(&mut self) {
|
pub(crate) fn ed25519_sign_raw(&mut self) {
|
||||||
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let stub_gen = || functor_stub(atom!("ed25519_sign"), 4);
|
||||||
|
let seed_bytes = self
|
||||||
|
.machine_st
|
||||||
|
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
|
||||||
|
|
||||||
|
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
|
||||||
|
|
||||||
let encoding = cell_as_atom!(self.deref_register(3));
|
let encoding = cell_as_atom!(self.deref_register(3));
|
||||||
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
|
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
|
||||||
|
|
||||||
let key_pair = match signature::Ed25519KeyPair::from_pkcs8(&key) {
|
let sig = skey.sign_raw(&data);
|
||||||
Ok(kp) => kp,
|
|
||||||
_ => {
|
|
||||||
self.machine_st.fail = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let sig = key_pair.sign(&data);
|
|
||||||
|
|
||||||
let sig_list = heap_loc_as_cell!(iter_to_heap_list(
|
let sig_list = heap_loc_as_cell!(iter_to_heap_list(
|
||||||
&mut self.machine_st.heap,
|
&mut self.machine_st.heap,
|
||||||
@@ -7679,25 +7656,21 @@ impl Machine {
|
|||||||
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
|
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "crypto-full")]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn ed25519_verify(&mut self) {
|
pub(crate) fn ed25519_verify_raw(&mut self) {
|
||||||
let key = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
let key_bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
|
||||||
|
let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap();
|
||||||
|
|
||||||
let encoding = cell_as_atom!(self.deref_register(3));
|
let encoding = cell_as_atom!(self.deref_register(3));
|
||||||
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
|
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
|
||||||
let stub_gen = || functor_stub(atom!("ed25519_verify"), 5);
|
|
||||||
|
let stub_gen = || functor_stub(atom!("ed25519_verify"), 4);
|
||||||
|
|
||||||
let signature = self
|
let signature = self
|
||||||
.machine_st
|
.machine_st
|
||||||
.integers_to_bytevec(self.machine_st.registers[4], stub_gen);
|
.integers_to_bytevec(self.machine_st.registers[4], stub_gen);
|
||||||
|
|
||||||
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
|
self.machine_st.fail = !pkey.verify_raw(&signature, &data);
|
||||||
|
|
||||||
match peer_public_key.verify(&data, &signature) {
|
|
||||||
Ok(_) => {}
|
|
||||||
_ => {
|
|
||||||
self.machine_st.fail = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
Reference in New Issue
Block a user