Added signing

This commit is contained in:
Ugljesa Jovanovic 2021-02-23 09:43:53 +01:00
parent d4955dc7cd
commit 7f703aa6b9
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
5 changed files with 4697 additions and 65 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,16 @@ class Blake2bState : Structure() {
val opaque = ByteArray(384) val opaque = ByteArray(384)
} }
//typedef struct crypto_sign_ed25519ph_state {
// crypto_hash_sha512_state hs;
//} crypto_sign_ed25519ph_state;
class Ed25519SignatureState : Structure() {
override fun getFieldOrder() = listOf("hs")
@JvmField
var hs: Hash512State = Hash512State()
}
// typedef struct crypto_secretstream_xchacha20poly1305_state { // typedef struct crypto_secretstream_xchacha20poly1305_state {
// unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]; // unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES];
@ -849,6 +859,7 @@ interface JnaLibsodiumInterface : Library {
publicKey: ByteArray, publicKey: ByteArray,
secretKey: ByteArray secretKey: ByteArray
): Int ): Int
// int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, // int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m,
// unsigned long long mlen, const unsigned char *n, // unsigned long long mlen, const unsigned char *n,
// const unsigned char *k) // const unsigned char *k)
@ -870,6 +881,7 @@ interface JnaLibsodiumInterface : Library {
nonce: ByteArray, nonce: ByteArray,
sessionKey: ByteArray sessionKey: ByteArray
): Int ): Int
// int crypto_box_seal(unsigned char *c, const unsigned char *m, // int crypto_box_seal(unsigned char *c, const unsigned char *m,
// unsigned long long mlen, const unsigned char *pk) // unsigned long long mlen, const unsigned char *pk)
fun crypto_box_seal( fun crypto_box_seal(
@ -894,20 +906,119 @@ interface JnaLibsodiumInterface : Library {
// // ---- Box end ---- // // ---- Box end ----
// //
// // ---- Sign start ---- // // ---- Sign start ----
// fun crypto_sign(message: Uint8Array, secretKey: Uint8Array) : Uint8Array
// fun crypto_sign_detached(message: Uint8Array, secretKey: Uint8Array) : Uint8Array // int crypto_sign(
// fun crypto_sign_ed25519_pk_to_curve25519(ed25519PublicKey: Uint8Array) : Uint8Array // unsigned char *sm, unsigned long long *smlen_p,
// fun crypto_sign_ed25519_sk_to_curve25519(ed25519SecretKey: Uint8Array) : Uint8Array // const unsigned char *m, unsigned long long mlen,
// fun crypto_sign_ed25519_sk_to_pk(ed25519SecretKey: Uint8Array) : Uint8Array // const unsigned char *sk)
// fun crypto_sign_ed25519_sk_to_seed(ed25519SecretKey: Uint8Array) : Uint8Array fun crypto_sign(
// fun crypto_sign_final_create(state: dynamic, secretKey: Uint8Array) : Uint8Array signedMessage: ByteArray,
// fun crypto_sign_final_verify(state: dynamic, signature: Uint8Array, publicKey: Uint8Array) : Boolean signedMessageLength: LongArray?,
// fun crypto_sign_init() : dynamic message: ByteArray,
// fun crypto_sign_keypair() : dynamic messageLength: Long,
// fun crypto_sign_open(signedMessage: Uint8Array, publicKey: Uint8Array) : Uint8Array secretKey: ByteArray
// fun crypto_sign_seed_keypair(seed: Uint8Array) : dynamic ) : Int
// fun crypto_sign_update(state: dynamic, message: Uint8Array) // int crypto_sign_open(
// fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean // unsigned char *m, unsigned long long *mlen_p,
// const unsigned char *sm, unsigned long long smlen,
// const unsigned char *pk)
fun crypto_sign_open(
message: ByteArray,
messageLength: LongArray?,
signedMessage: ByteArray,
signedMessageLength: Long,
publicKey: ByteArray
) : Int
// int crypto_sign_detached(
// unsigned char *sig, unsigned long long *siglen_p,
// const unsigned char *m, unsigned long long mlen,
// const unsigned char *sk)
fun crypto_sign_detached(
signature: ByteArray,
signatureLength: LongArray?,
message: ByteArray,
messageLength: Long,
secretKey: ByteArray
) : Int
// int crypto_sign_verify_detached(
// const unsigned char *sig,
// const unsigned char *m,
// unsigned long long mlen,
// const unsigned char *pk)
fun crypto_sign_verify_detached(
signature: ByteArray,
message: ByteArray,
messageLength: Long,
publicKey: ByteArray
) : Int
// int crypto_sign_ed25519_pk_to_curve25519(
// unsigned char *curve25519_pk,
// const unsigned char *ed25519_pk)
fun crypto_sign_ed25519_pk_to_curve25519(
curve25519PublicKey: ByteArray,
ed25519PublicKey: ByteArray
) : Int
// int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
// const unsigned char *ed25519_sk)
fun crypto_sign_ed25519_sk_to_curve25519(
curve25519SecretKey: ByteArray,
ed25519SecretKey: ByteArray
) : Int
// int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk)
fun crypto_sign_ed25519_sk_to_pk(
ed25519PublicKey: ByteArray,
ed25519SecretKey: ByteArray
) : Int
// int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
// const unsigned char *sk)
fun crypto_sign_ed25519_sk_to_seed(
seed: ByteArray,
ed25519SecretKey: ByteArray
) : Int
// int crypto_sign_init(crypto_sign_state *state);
fun crypto_sign_init(state: Ed25519SignatureState)
// int crypto_sign_update(crypto_sign_state *state,
// const unsigned char *m, unsigned long long mlen)
fun crypto_sign_update(
state: Ed25519SignatureState,
message: ByteArray,
messageLength: Long
) : Int
// int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig,
// unsigned long long *siglen_p,
// const unsigned char *sk)
fun crypto_sign_final_create(
state: Ed25519SignatureState,
signature: ByteArray,
signatureLength: LongArray?,
secretKey: ByteArray
) : Int
// int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig,
// const unsigned char *pk)
fun crypto_sign_final_verify(
state: Ed25519SignatureState,
signature: ByteArray,
publicKey: ByteArray
) : Int
// int crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
fun crypto_sign_keypair(
publicKey: ByteArray, secretKey: ByteArray
)
// int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
// const unsigned char *seed)
fun crypto_sign_seed_keypair(
publicKey: ByteArray,
secretKey: ByteArray,
seed: ByteArray
) : Int
// //
// //
// // ---- Sign end ---- // // ---- Sign end ----
@ -930,18 +1041,7 @@ interface JnaLibsodiumInterface : Library {
// //
// // ---- Password hashing end ---- // // ---- Password hashing end ----
// //
// // ---- Utils ----
//
// fun memcmp(first: Uint8Array, second: Uint8Array) : Boolean
// fun memzero(data: Uint8Array)
// fun pad(data : Uint8Array, blocksize: Int) : Uint8Array
// fun unpad(data: Uint8Array, blocksize: Int) : Uint8Array
// fun to_base64(data: Uint8Array, variant: Int) : String
// fun to_hex(data: Uint8Array) : String
// fun to_string(data: Uint8Array) : String
// fun from_base64(data: String, variant: Int): Uint8Array
// fun from_hex(data : String): Uint8Array
// fun from_string(data : String): Uint8Array
// //
// // ---- > ---- Random ---- < ----- // // ---- > ---- Random ---- < -----
// //

View File

@ -1,9 +1,9 @@
package com.ionspin.kotlin.crypto.signature package com.ionspin.kotlin.crypto.signature
import com.goterl.lazycode.lazysodium.interfaces.Sign import com.ionspin.kotlin.crypto.Ed25519SignatureState
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual typealias SignatureState = Sign.StateCryptoSign actual typealias SignatureState = Ed25519SignatureState
actual object Signature { actual object Signature {
actual fun init(): SignatureState { actual fun init(): SignatureState {
@ -11,7 +11,7 @@ actual object Signature {
} }
actual fun update(state: SignatureState, data: UByteArray) { actual fun update(state: SignatureState, data: UByteArray) {
sodium.crypto_sign_update(state, data.asByteArray(), data.size.toLong()) sodiumJna.crypto_sign_update(state, data.asByteArray(), data.size.toLong())
} }
actual fun finalCreate( actual fun finalCreate(
@ -19,7 +19,7 @@ actual object Signature {
secretKey: UByteArray secretKey: UByteArray
): UByteArray { ): UByteArray {
val signature = UByteArray(crypto_sign_BYTES) val signature = UByteArray(crypto_sign_BYTES)
sodium.crypto_sign_final_create( sodiumJna.crypto_sign_final_create(
state, state,
signature.asByteArray(), signature.asByteArray(),
null, null,
@ -33,7 +33,7 @@ actual object Signature {
signature: UByteArray, signature: UByteArray,
publicKey: UByteArray publicKey: UByteArray
) { ) {
val verificationResult = sodium.crypto_sign_final_verify( val verificationResult = sodiumJna.crypto_sign_final_verify(
state, state,
signature.asByteArray(), signature.asByteArray(),
publicKey.asByteArray() publicKey.asByteArray()
@ -50,7 +50,7 @@ actual object Signature {
actual fun keypair(): SignatureKeyPair { actual fun keypair(): SignatureKeyPair {
val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES)
sodium.crypto_sign_keypair( sodiumJna.crypto_sign_keypair(
publicKey.asByteArray(), publicKey.asByteArray(),
secretKey.asByteArray(), secretKey.asByteArray(),
) )
@ -67,7 +67,7 @@ actual object Signature {
val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES)
sodium.crypto_sign_seed_keypair( sodiumJna.crypto_sign_seed_keypair(
publicKey.asByteArray(), publicKey.asByteArray(),
secretKey.asByteArray(), secretKey.asByteArray(),
seed.asByteArray() seed.asByteArray()
@ -76,13 +76,13 @@ actual object Signature {
} }
/** /**
* The sodium.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. * The sodiumJna.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk.
* The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodium.crypto_sign_BYTES + mlen bytes long. * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodiumJna.crypto_sign_BYTES + mlen bytes long.
*/ */
actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray {
val signedMessage = UByteArray(message.size + crypto_sign_BYTES) val signedMessage = UByteArray(message.size + crypto_sign_BYTES)
sodium.crypto_sign( sodiumJna.crypto_sign(
signedMessage.asByteArray(), signedMessage.asByteArray(),
null, null,
message.asByteArray(), message.asByteArray(),
@ -94,13 +94,13 @@ actual object Signature {
} }
/** /**
* The sodium.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. * The sodiumJna.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk.
* If the signature is doesn't appear to be valid, the function throws an exception * If the signature is doesn't appear to be valid, the function throws an exception
*/ */
actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray {
val message = UByteArray(signedMessage.size - crypto_sign_BYTES) val message = UByteArray(signedMessage.size - crypto_sign_BYTES)
val verificationResult = sodium.crypto_sign_open( val verificationResult = sodiumJna.crypto_sign_open(
message.asByteArray(), message.asByteArray(),
null, null,
signedMessage.asByteArray(), signedMessage.asByteArray(),
@ -115,13 +115,13 @@ actual object Signature {
/** /**
* In detached mode, the signature is stored without attaching a copy of the original message to it. * In detached mode, the signature is stored without attaching a copy of the original message to it.
* The sodium.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, * The sodiumJna.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk,
* and puts the signature into sig, which can be up to sodium.crypto_sign_BYTES bytes long. * and puts the signature into sig, which can be up to sodiumJna.crypto_sign_BYTES bytes long.
*/ */
actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray {
val signature = UByteArray(crypto_sign_BYTES) val signature = UByteArray(crypto_sign_BYTES)
sodium.crypto_sign_detached( sodiumJna.crypto_sign_detached(
signature.asByteArray(), signature.asByteArray(),
null, null,
message.asByteArray(), message.asByteArray(),
@ -133,7 +133,7 @@ actual object Signature {
} }
/** /**
* The sodium.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length * The sodiumJna.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length
* is mlen bytes, using the signer's public key pk. * is mlen bytes, using the signer's public key pk.
*/ */
actual fun verifyDetached( actual fun verifyDetached(
@ -142,7 +142,7 @@ actual object Signature {
publicKey: UByteArray publicKey: UByteArray
) { ) {
val verificationResult = sodium.crypto_sign_verify_detached( val verificationResult = sodiumJna.crypto_sign_verify_detached(
signature.asByteArray(), signature.asByteArray(),
message.asByteArray(), message.asByteArray(),
message.size.toLong(), message.size.toLong(),
@ -155,11 +155,11 @@ actual object Signature {
} }
/** /**
* The sodium.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. * The sodiumJna.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk.
*/ */
actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray { actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray {
val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES) val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES)
sodium.crypto_sign_ed25519_sk_to_curve25519( sodiumJna.crypto_sign_ed25519_sk_to_curve25519(
x25519PublicKey.asByteArray(), x25519PublicKey.asByteArray(),
ed25519PublicKey.asByteArray() ed25519PublicKey.asByteArray()
) )
@ -168,7 +168,7 @@ actual object Signature {
actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray { actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray {
val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES) val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES)
sodium.crypto_sign_ed25519_sk_to_curve25519( sodiumJna.crypto_sign_ed25519_sk_to_curve25519(
x25519SecretKey.asByteArray(), x25519SecretKey.asByteArray(),
ed25519SecretKey.asByteArray() ed25519SecretKey.asByteArray()
) )
@ -176,13 +176,13 @@ actual object Signature {
} }
/** /**
* The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. * The secret key actually includes the seed (either a random seed or the one given to sodiumJna.crypto_sign_seed_keypair()) as well as the public key.
* While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
*/ */
actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray {
val seed = UByteArray(crypto_sign_SEEDBYTES) val seed = UByteArray(crypto_sign_SEEDBYTES)
sodium.crypto_sign_ed25519_sk_to_seed( sodiumJna.crypto_sign_ed25519_sk_to_seed(
seed.asByteArray(), seed.asByteArray(),
secretKey.asByteArray() secretKey.asByteArray()
) )
@ -192,13 +192,13 @@ actual object Signature {
} }
/** /**
* The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. * The secret key actually includes the seed (either a random seed or the one given to sodiumJna.crypto_sign_seed_keypair()) as well as the public key.
* While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
*/ */
actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray {
val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES)
sodium.crypto_sign_ed25519_sk_to_pk( sodiumJna.crypto_sign_ed25519_sk_to_pk(
publicKey.asByteArray(), publicKey.asByteArray(),
secretKey.asByteArray() secretKey.asByteArray()
) )