ADDED: Public key signatures and signature verification with Ed25519

This commit is contained in:
Markus Triska
2020-05-20 18:30:34 +02:00
parent a0544cc345
commit ad3be5c848
4 changed files with 82 additions and 3 deletions

View File

@@ -291,7 +291,9 @@ pub enum SystemClauseType {
CryptoDataHKDF,
CryptoPasswordHash,
CryptoDataEncrypt,
CryptoDataDecrypt
CryptoDataDecrypt,
Ed25519Sign,
Ed25519Verify
}
impl SystemClauseType {
@@ -480,6 +482,8 @@ impl SystemClauseType {
&SystemClauseType::CryptoPasswordHash => clause_name!("$crypto_password_hash"),
&SystemClauseType::CryptoDataEncrypt => clause_name!("$crypto_data_encrypt"),
&SystemClauseType::CryptoDataDecrypt => clause_name!("$crypto_data_decrypt"),
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
}
}
@@ -648,6 +652,8 @@ impl SystemClauseType {
("$crypto_password_hash", 4) => Some(SystemClauseType::CryptoPasswordHash),
("$crypto_data_encrypt", 5) => Some(SystemClauseType::CryptoDataEncrypt),
("$crypto_data_decrypt", 5) => Some(SystemClauseType::CryptoDataDecrypt),
("$ed25519_sign", 3) => Some(SystemClauseType::Ed25519Sign),
("$ed25519_verify", 3) => Some(SystemClauseType::Ed25519Verify),
_ => None,
}
}

View File

@@ -9,7 +9,7 @@
and strings have the advantage that the atom table remains unmodified.
Especially for cryptographic applications, it as an advantage that
using strings leaves little trace of what was processed in the system,
using strings leaves little trace of what was processed in the system.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
:- module(crypto,
@@ -21,6 +21,8 @@
crypto_password_hash/3, % +Password, -Hash, +Options
crypto_data_encrypt/6, % +PlainText, +Algorithm, +Key, +IV, -CipherText, +Options
crypto_data_decrypt/6, % +CipherText, +Algorithm, +Key, +IV, -PlainText, +Options
ed25519_sign/4, % +PrivateKey, +Data, -Signature, +Options
ed25519_verify/4, % +PublicKey, +Data, -Signature, +Options
crypto_name_curve/2, % +Name, -Curve
crypto_curve_order/2, % +Curve, -Order
crypto_curve_generator/2, % +Curve, -Generator
@@ -624,6 +626,44 @@ encoding_bytes(utf8, Cs, Bs) :-
; domain_error(encryption_encoding, Cs, crypto)
).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Digital signatures with Ed25519
===============================
ed25519_sign(+Key, +Data, -Signature, +Options)
Key and Data must be lists of characters. Key is a private key in
PKCS#8 (v1 or v2) DER format. Sign Data with Key, yielding
Signature as a list of hexadecimal characters.
ed25519_verify(+Key, +Data, +Signature, +Options)
Key and Data must be lists of characters. Key is a public key in
PKCS#8 DER format. Succeeds if Data was signed with the private key
corresponding to Key, where Signature is a list of hexadecimal
characters as generated by ed25519_sign/4. Fails otherwise.
Currently, the only option for both predicates is:
- encoding(+Encoding)
The default encoding of Data is utf8. The alternative is octet,
which treats Data as a list of raw bytes.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ed25519_sign(Key0, Data0, Signature, Options) :-
options_data_bytes(Options, Data0, Data),
encoding_bytes(octet, Key0, Key),
'$ed25519_sign'(Key, Data, Signature0),
hex_bytes(Signature, Signature0).
ed25519_verify(Key0, Data0, Signature0, Options) :-
options_data_bytes(Options, Data0, Data),
encoding_bytes(octet, Key0, Key),
hex_bytes(Signature0, Signature),
'$ed25519_verify'(Key, Data, Signature).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Modular multiplicative inverse.

View File

@@ -40,7 +40,7 @@ use crate::crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
use ring::rand::{SecureRandom, SystemRandom};
use ring::{digest,hkdf,pbkdf2,aead,error};
use ring::{digest,hkdf,pbkdf2,aead,error,signature};
use ripemd160::{Ripemd160, Digest};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
use blake2::{Blake2s, Blake2b};
@@ -5448,6 +5448,38 @@ impl MachineState {
self.unify(self[temp_v!(5)], complete_string);
}
&SystemClauseType::Ed25519Sign => {
let stub1 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
let key = self.integers_to_bytevec(temp_v!(1), stub1);
let stub2 = MachineError::functor_stub(clause_name!("ed25519_sign"), 4);
let data = self.integers_to_bytevec(temp_v!(2), stub2);
let key_pair = match signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(&key) {
Ok(kp) => { kp }
_ => { self.fail = true; return Ok(()); }
};
let sig = key_pair.sign(&data);
let sig_list =
Addr::HeapCell(self.heap.to_list(sig.as_ref().iter().map(|b| HeapCellValue::from(Addr::Fixnum(*b as isize)))));
self.unify(self[temp_v!(3)], sig_list);
}
&SystemClauseType::Ed25519Verify => {
let stub1 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
let key = self.integers_to_bytevec(temp_v!(1), stub1);
let stub2 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
let data = self.integers_to_bytevec(temp_v!(2), stub2);
let stub3 = MachineError::functor_stub(clause_name!("ed25519_verify"), 4);
let signature = self.integers_to_bytevec(temp_v!(3), stub3);
let peer_public_key = signature::UnparsedPublicKey::new(&signature::ED25519, &key);
match peer_public_key.verify(&data, &signature) {
Ok(_) => { }
_ => { self.fail = true; return Ok(()); }
}
}
};
return_from_clause!(self.last_call, self)