...
 
Commits (2)
type t = { body : BlockBody.t; signatures : Signature.t array }
open Core
type t = { body : BlockBody.t; signatures : Signature.t list }
let format { body; signatures } =
Printf.sprintf "%s%s\n"
(BlockBody.format body)
(Signatures.format signatures)
type t = { body : BlockBody.t; signatures : Signature.t array }
type t = { body : BlockBody.t; signatures : Signature.t list }
val format : t -> string
......@@ -16,7 +16,7 @@ type t = {
let format {
version; layer; previous_hash; hash_algorithm; fingerprint_algorithm;
expires_at; minimum_required_power; commands; signature_declarations } =
Format.sprintf "YAYAKA %s\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n%s\n%d\n%s\n"
Format.sprintf "YAYAKA %s\n%d\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n"
version
layer
(Option.value_map previous_hash ~f:YayakaHash.format ~default:"\n")
......@@ -24,11 +24,5 @@ let format {
(ExpirationDateTime.to_string expires_at)
(Power.to_int minimum_required_power)
(HashAlgorithm.to_string fingerprint_algorithm)
(List.length commands)
(commands
|> List.map ~f:YayakaCommand.format
|> String.concat ~sep:"\n")
(List.length signature_declarations)
(signature_declarations
|> List.map ~f:SignatureDeclaration.format
|> String.concat ~sep:"\n")
(Commands.format commands)
(SignatureDeclarations.format signature_declarations)
module YayakaCommand = Command
open Core
type t = YayakaCommand.t list
let format declarations =
Printf.sprintf "%d\n%s"
(List.length declarations)
(List.map declarations ~f:YayakaCommand.format |> String.concat ~sep:"\n")
type t = Command.t list
val format : t -> string
......@@ -51,3 +51,8 @@ let verify_rsa ~hash_algorithm ~key:PublicKey.{ key; _ } ~sign body =
let verify ~sign:{ hash_algorithm; key; body } block =
match key.PublicKey.algorithm with
| RSA -> verify_rsa ~hash_algorithm ~key ~sign:body block
let format { body; _ } =
Printf.sprintf "%d\n%s"
(1 + String.count body ~f:(( = ) '\n'))
body
......@@ -8,3 +8,5 @@ val sign :
val verify :
sign:t -> BlockBody.t -> bool
val format : t -> string
open Core
type t = SignatureDeclaration.t list
let format declarations =
Printf.sprintf "%d\n%s"
(List.length declarations)
(List.map declarations ~f:SignatureDeclaration.format |> String.concat ~sep:"\n")
type t = SignatureDeclaration.t list
val format : t -> string
open Core
type t = Signature.t list
let format signatures =
(List.map signatures ~f:Signature.format |> String.concat ~sep:"\n")
type t = Signature.t list
val format : t -> string
open Core
open YayakaChain
module Test = Alcotest
open Support
let test_format () =
Test.(check string) "format"
"\
YAYAKA 0.1\n\
1\n\
sha1\n\
hvfkN/qlp/zhXR3cuerq6jd2Z7g=\n\
sha256\n\
20190207120915\n\
3\n\
sha1\n\
2\n\
7\n\
add\n\
rsa\n\
2\n\
-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDAOCHAgMBAAE=\n\
-----END PUBLIC KEY-----\n\
\n\
3\n\
update\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
3\n\
2\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
+gf0YWKHMzO0/mCFlB9AivKRlD0=\n\
sha256\n\
1\n\
FIcMDik/4+flC4gRsH76DReJhBqu6ZT2gO7kc4VEd5LryEoI/oxSH45PLW5glx0vCIoowirC87ZS\
JVMTQn0S1FAhTwxZqW2ACgmmjFp0H7/rsK8j1UtjB1qHe/soxdcdqfM9/OswSEACqEeTtSlFbzVr\
MruO3o6mfLIZZ3ay8ak=\n\
1\n\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo=\n"
Block.(format {
body = BlockBody.{
version = "0.1";
layer = 1;
previous_hash = Some Hash.{
algorithm = HashAlgorithm.Sha1;
hash = "hvfkN/qlp/zhXR3cuerq6jd2Z7g="};
hash_algorithm = HashAlgorithm.Sha256;
fingerprint_algorithm = HashAlgorithm.Sha1;
expires_at = expiration_date_time_of_string "20190207120915";
minimum_required_power = Option.value_exn (Power.of_int 3);
commands = [
Command.AddPublicKey {
algorithm = PublicKeyAlgorithm.RSA;
power = Option.value_exn (Power.of_int 2);
key = "\
-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDAOCHAgMBAAE=\n\
-----END PUBLIC KEY-----\n" };
Command.UpdatePower {
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
power = Option.value_exn (Power.of_int 3)
};
];
signature_declarations = [
SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
};
SignatureDeclaration.{
fingerprint = "+gf0YWKHMzO0/mCFlB9AivKRlD0=";
hash_algorithm = HashAlgorithm.Sha256;
};
]
};
signatures = [
Signature.{
hash_algorithm = HashAlgorithm.Sha1;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
FIcMDik/4+flC4gRsH76DReJhBqu6ZT2gO7kc4VEd5LryEoI/oxSH45PLW5glx0vCIoowirC87ZS\
JVMTQn0S1FAhTwxZqW2ACgmmjFp0H7/rsK8j1UtjB1qHe/soxdcdqfM9/OswSEACqEeTtSlFbzVr\
MruO3o6mfLIZZ3ay8ak="
};
Signature.{
hash_algorithm = HashAlgorithm.Sha256;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo="
}
]
});
Test.(check string) "minimum"
"\
YAYAKA 0.1\n\
1\n\
sha1\n\
hvfkN/qlp/zhXR3cuerq6jd2Z7g=\n\
sha256\n\
20190207120915\n\
3\n\
sha1\n\
0\n\
\n\
0\n\
\n\
\n"
Block.(format {
body = BlockBody.{
version = "0.1";
layer = 1;
previous_hash = Some Hash.{
algorithm = HashAlgorithm.Sha1;
hash = "hvfkN/qlp/zhXR3cuerq6jd2Z7g="};
hash_algorithm = HashAlgorithm.Sha256;
fingerprint_algorithm = HashAlgorithm.Sha1;
expires_at = expiration_date_time_of_string "20190207120915";
minimum_required_power = Option.value_exn (Power.of_int 3);
commands = [];
signature_declarations = []
};
signatures = []
})
let block_tests = [
"format", `Quick, test_format;
]
let () =
Test.run "Block" [
"Block", block_tests;
]
open Core
open YayakaChain
module Test = Alcotest
let test_format () =
Test.(check string) "0"
"0\n"
(Commands.format []);
Test.(check string) "2" "\
2\n\
7\n\
add\n\
rsa\n\
2\n\
-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDAOCHAgMBAAE=\n\
-----END PUBLIC KEY-----\n\
\n\
3\n\
update\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
3"
(Commands.format [
Command.AddPublicKey {
algorithm = PublicKeyAlgorithm.RSA;
power = Option.value_exn (Power.of_int 2);
key = "\
-----BEGIN PUBLIC KEY-----\n\
MB4wDQYJKoZIhvcNAQEBBQADDQAwCgIDAOCHAgMBAAE=\n\
-----END PUBLIC KEY-----\n"
};
Command.UpdatePower {
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
power = Option.value_exn (Power.of_int 3)
};
])
let signatures_tests = [
"format", `Quick, test_format;
]
let () =
Test.run "Commands" [
"Commands", signatures_tests;
]
......@@ -10,5 +10,9 @@
blockBody_test
util_test
signatureDeclaration_test
signature_test)
signature_test
block_test
commands_test
signatureDeclarations_test
signatures_test)
(libraries alcotest yayakaChain))
open YayakaChain
module Test = Alcotest
let test_format () =
Test.(check string) "0"
"0\n"
(SignatureDeclarations.format []);
Test.(check string) "2" "\
2\n\
qZk+NkcGgWq6PiVxeFDCbJzQ2J0=\n\
sha1\n\
+gf0YWKHMzO0/mCFlB9AivKRlD0=\n\
sha256"
(SignatureDeclarations.format [
SignatureDeclaration.{
fingerprint = "qZk+NkcGgWq6PiVxeFDCbJzQ2J0=";
hash_algorithm = HashAlgorithm.Sha1;
};
SignatureDeclaration.{
fingerprint = "+gf0YWKHMzO0/mCFlB9AivKRlD0=";
hash_algorithm = HashAlgorithm.Sha256;
};
])
let signatures_tests = [
"format", `Quick, test_format;
]
let () =
Test.run "SignatureDeclarations" [
"SignatureDeclarations", signatures_tests;
]
......@@ -393,9 +393,59 @@ let test_verify () =
]
})
let test_format () =
Test.(check string) "1 line" "\
1\n\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo="
Signature.(format {
hash_algorithm = HashAlgorithm.Sha256;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo="
});
Test.(check string) "3 lines" "\
3\n\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\n\
hKwzjJkpZxKqM4MGiwo=\n"
Signature.(format {
hash_algorithm = HashAlgorithm.Sha256;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\n\
hKwzjJkpZxKqM4MGiwo=\n"
})
let signature_tests = [
"sign", `Quick, test_sign;
"verify", `Quick, test_verify;
"format", `Quick, test_format;
]
let () =
......
open YayakaChain
module Test = Alcotest
open Support
let test_format () =
Test.(check string) "0"
""
(Signatures.format []);
Test.(check string) "2" "\
1\n\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo=\n\
3\n\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\n\
hKwzjJkpZxKqM4MGiwo=\n"
(Signatures.format [
Signature.{
hash_algorithm = HashAlgorithm.Sha256;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\
hKwzjJkpZxKqM4MGiwo="
};
Signature.{
hash_algorithm = HashAlgorithm.Sha256;
key = {
algorithm = PublicKeyAlgorithm.RSA;
key = "\
-----BEGIN PUBLIC KEY-----\n\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC83PxbqZrsZEbQzFyULef0X3ti\n\
tp2Hnv8f9uaevB1mtUSflc+cJOytKe7AFZEYkA3vWduSC4/1X8KbXs3A6BwD72ji\n\
v6OqtM2hfROWEgx9xwC53bGtvf9EdMmSUncjGNfCdOvXqtFDZd+v7L5XTXO4D+Nj\n\
znYGB5RL2EMLh4gcgQIDAQAB\n\
-----END PUBLIC KEY-----\n";
power = to_power 3
};
body = "\
QkCpjmf4UfLmhunz+/yYpo/zxrysJiFnT1aVKrT7ueFUDmltmFj+jt/MVBoB5Vb9zl68+TfCbwgw\
I3jMwM6ZtJno+Vc6dks2lEkioc2dZ2F4jf0/aZ+KRK02evRATZD4gLq0jjmgS+XDCOafcbmJcjsr\n\
hKwzjJkpZxKqM4MGiwo=\n"
}
])
let signatures_tests = [
"format", `Quick, test_format;
]
let () =
Test.run "Signatures" [
"Signatures", signatures_tests;
]