Files
herolib/lib/crypt/ed25519/privkey25519.v
2024-12-25 12:38:51 +01:00

86 lines
2.6 KiB
V

module ed25519
import libsodium
// import encoding.hex
// holds signing and private key
// private key is derivative from signing key
// signkey_bytes is the seed to generate a signing key from which can then generate priv key
pub struct PrivKey25519 {
pub:
signkey_bytes []u8 // signing key in bytes
signkey libsodium.SigningKey // master key (is a signing key)
privkey libsodium.PrivateKey // derivated from master key
pubkey PubKey25519
}
pub struct PubKey25519 {
pub:
ed_bytes []u8 // for signing
curve_bytes []u8 // target = remote public key (to encrypt) , also called X25519
}
pub fn new_private_key_25519() PrivKey25519 {
mut seed := []u8{}
// generate a new random seed
for _ in 0 .. 32 {
seed << u8(libsodium.randombytes_random())
}
signkey := libsodium.new_ed25519_signing_key_seed(seed)
privkey := libsodium.new_private_key_from_signing_ed25519(signkey)
pubkey := priv_to_public_key(signkey)
return PrivKey25519{
signkey: signkey
privkey: privkey
signkey_bytes: seed
pubkey: pubkey
}
}
// retrieve the master public key from PrivKey object
// this is the public key as need to be shared to a remote user to verify that we signed with our private key
// is shared as hex key in string format (66 chars)
fn priv_to_public_key(priv_sign_key libsodium.SigningKey) PubKey25519 {
x := priv_sign_key.verify_key.public_key
mut ed_bytes := []u8{len: x.len}
unsafe { C.memcpy(ed_bytes.data, &x[0], x.len) }
curve_bytes := []u8{len: libsodium.public_key_size}
libsodium.crypto_sign_ed25519_pk_to_curve25519(curve_bytes.data, ed_bytes.data)
return PubKey25519{
ed_bytes: ed_bytes
curve_bytes: curve_bytes
}
}
// encrypt data which can only be read by whoever has the private key for this public key
pub fn (privkey PrivKey25519) encrypt_for_remote(pubkey PubKey25519, data []u8) ![]u8 {
box := libsodium.new_box(privkey.privkey, pubkey.curve_bytes)
return box.encrypt(data)
}
// verify a signed data and decrypt,
pub fn (privkey PrivKey25519) decrypt(data []u8) []u8 {
box := libsodium.new_box(privkey.privkey, privkey.pubkey.curve_bytes)
decrypted := box.decrypt(data)
return decrypted
}
// sign data with our signing key.
// data is bytestr.
// output is []u8 bytestring.
// to get bytes from string do: mystring.bytes().
pub fn (key PrivKey25519) sign(data []u8) []u8 {
return key.signkey.sign(data)
}
// verify the signature
pub fn (key PubKey25519) verify(signature []u8) bool {
v := [libsodium.public_key_size]u8{}
// unsafe { C.memcpy(&v[0], key.ed_bytes, libsodium.public_key_size) }
// vk:=libsodium.VerifyKey{public_key: v}
// return vk.verify(signature)
return true
}