gmsm/drbg/ctr_drbg_test.go

306 lines
12 KiB
Go

package drbg
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"testing"
"github.com/emmansun/gmsm/sm4"
)
var ctrtests = []struct {
gm bool
cipherProvider func(key []byte) (cipher.Block, error)
keyLen int
entropyInput string
nonce string
personalizationString string
v0 string
key0 string
entropyInputReseed string
additionalInputReseed string
v1 string
key1 string
additionalInput1 string
v2 string
key2 string
additionalInput2 string
returnbits1 string
v3 string
key3 string
}{
{ // AES-128, without additional input
false,
aes.NewCipher,
16,
"0f65da13dca407999d4773c2b4a11d85",
"5209e5b4ed82a234",
"",
"80941680713df715056fb2a3d2e998b2",
"0c42ea6804303954deb197a07e6dbdd2",
"1dea0a12c52bf64339dd291c80d8ca89",
"",
"f2bacbb233252fba35fb0582f9286179", // v1
"32fbfd0109f364ed21ef21a6e5c763e7", //key1
"",
"99003d630bba500fe17c37f8c7331bf6", // v2
"757c8eb766f9aaa4650d6500b58624a3", //key2
"",
"2859cc468a76b08661ffd23b28547ffd0997ad526a0f51261b99ed3a37bd407bf418dbe6c6c3e26ed0ddefcb7474d899bd99f3655427519fc5b4057bcaf306d4",
"5907ab447a88e5106753507cc97e0fd5",
"e421ff2445e04992faf36cf9a5eaf1f9",
},
{ // AES-128, without additional input
false,
aes.NewCipher,
16,
"c9b8d7eb0afa5889e7f9b78a50ed453c",
"3058ba347ecd11b1",
"",
"b4e0180e3af0d99592249db33a29cc4e",
"1621bebef7e9215078459ecc74baffbc",
"643686b86266d9111f29eb389e1184b4",
"",
"7574911eeb85d56d385f0c8c99965c4a", // v1
"a4c515266cb5986825a503b39d5f398c", //key1
"",
"abca3ea049e405d3826f43e54e08c8f7", // v2
"edcdf23f60d3988a4d235798aa0d33a2", //key2
"",
"0a8ccadc1c5cbd20b8ce32f942505e654b91a4e9410e0ea627c961d632d3be71d6a7dfd64b8f70d28ff91869b92ced908b454936b6d18fcddd7fb77216ccc404",
"1d57b4e09fd920d91877a0737559ee29",
"e83e07722d26779d0b76a52a629b211b",
},
{ // AES-128, with additional input
false,
aes.NewCipher,
16,
"285da6cf762552634636bfee3400b156",
"8f8bada74820cb43",
"",
"ad2af7e4c84337cfc3116d59f02c54a8", // v0
"c92780982442d348cc7363dfc96a999d", // key0
"b4699b33354a83bfed115f770f32db0b", // EntropyInputReseed
"38bfec9a10e6e40c106841dae48dc3b8", // AdditionalInputReseed
"923f37427a8e10bf945249a5b790769a", // v1
"57004c8a776f5c702e83ff56acc32dcc", // key1
"629ead5bacfac8235711ffeb22f57558", // AdditionalInput1
"7ade619ed91092987d8a1d244605f85f", // v2
"3b5f92f511c10fef2f640de2cd8c9049", // key2
"dd8a02ee668ca3e03949b38cb6e6b4df", // AdditionalInput2
"e555aa4432bde04dcf0f0b03ead187b31df06653d444234b5c1bfc11b224285f2fb2b6cdd5a9ae6f13d99bd02c3c9fe9c3c1be46a600f5f757ab4574af893501",
"f5dac2375e820f797c6f1258147d8ea7", // v3
"6bc01c1518fe9f9dfbbb08d97c34db1e", // key3
},
{ // AES-192, without additional input
false,
aes.NewCipher,
24,
"b11d8b104a7ced9b9f37e5d92ad3dfcbb817552b1ae88f6a",
"017510f270c66586a51313eadc32b07e",
"",
"9e5767ab537fe663c71e4054ba618c8d", // v0
"b9b3d73bc0c784a7d78db344109707c73abbff7dc2dfa864", // key0
"6d14cfb36f30c9c1a1ba0e0a32c2f99d1b47f219a3a8ac14", // EntropyInputReseed
"", // AdditionalInputReseed
"c8563c5a4adc3b579f79f898c4b69854", // v1
"3e18d4984d454e5f986e49bfa7a569dab3667ece8130cba1", // key1
"", // AdditionalInput1
"087a3112e191f60619acae2a556f333b", // v2
"b42a24cbb9e8c014bb65350afa28a67b273a41e599bde5b8", // key2
"", // AdditionalInput2
"53fbba563ae014ebc080767aab8452a9f36ce40bbf68f1a12dc0a6388c870c8dfa4250526cbc8c983fee6449903c6bd7c2c02e327680a66b464267edbc4e6797",
"84f344f8277841e920464ca475b10276", // v3
"1f5e987ac2259b7072867e4ae59167094d0162111062f6f8", // key3
},
{ // AES-192, with additional input
false,
aes.NewCipher,
24,
"3a09c9cc5e01f152ea2ed3021d49b4d6386aa6f04521ebde",
"490bd4ee628cf9615035543e70fce4e2",
"",
"59a45ccbc3864f79b896c30d4a231d46", // v0
"a4283dc9450ac97bf22c387082e3816728243473cedaa2af", // key0
"df06e5668d41a6fa7660aef477eff7a0ffc0542c1cd406d5", // EntropyInputReseed
"59b8c26626aab69e462752722f19450d12e2c0e959882d4d06ef4177e396855d", // AdditionalInputReseed
"5857d49a1552923931926dca1682fbc2", // v1
"9c4d7784fe341619e21f2535d404866df3b75e9a7940d471", // key1
"28e57a9128e479985cce391e98127fd126f37ad0f317fd5f97b8c18e762f360b", // AdditionalInput1
"bb8ed7bcbe1203be861b8e6570fe116b", // v2
"6a8fddde995255f89ea3c9454cc481045ff0e16ce5a34693", // key2
"d488672b52e867816178369f542190685bbe8672720c1943d8a4378cc9b9dd0c", // AdditionalInput2
"5c233e2850e4981bab0f6513a76ca2c9f9f97b89b7fedd3d9aaffecf305d89fd5306cf24715895ad9ba7dac8c389fd87f95b4973003150871fa281e962f270cb",
"1cf82a0638c421bb43401943498d0f88", // v3
"5dec9ad1f5f3d0e7bb59ae581097a3f616e443e4f5bd804a", // key3
},
{ // AES-256, without additional input
false,
aes.NewCipher,
32,
"2d4c9f46b981c6a0b2b5d8c69391e569ff13851437ebc0fc00d616340252fed5",
"0bf814b411f65ec4866be1abb59d3c32",
"",
"446ce986bd722ad1a514ebb7d274ec99", // v0
"d64160c3e965f377caef625c7eb21dd37728bcf84bfc23b92e267611feaffda8", // key0
"93500fae4fa32b86033b7a7bac9d37e710dcc67ca266bc8607d665937766d207", // EntropyInputReseed
"", // AdditionalInputReseed
"0b8e38a54036f1ba80a2880d4f17bb09", // v1
"50d9feb33fc77303b83232b7deded04f1bfa4afaa937712f88458d6b64c046c5", // key1
"", // AdditionalInput1
"84b0a849c5459e27fe7f8c5db26fa13d", // v2
"a2203a6f082ecdc0cd38f0b3b19f1a8cd6a5f110a13bb488c1e70f9f95a93024", // key2
"", // AdditionalInput2
"322dd28670e75c0ea638f3cb68d6a9d6e50ddfd052b772a7b1d78263a7b8978b6740c2b65a9550c3a76325866fa97e16d74006bc96f26249b9f0a90d076f08e5",
"de67dd5f9a431fc46dd1825cd1a2bff3", // v3
"de721178a341a85eb54a2f7e2b3cd4bcc201417e739eb183fa958f9af8535b2c", // key3
},
{ // AES-256, with additional input
false,
aes.NewCipher,
32,
"6f60f0f9d486bc23e1223b934e61c0c78ae9232fa2e9a87c6dacd447c3f10e9e",
"401e3f87762fa8a14ab232ccb8480a2f",
"",
"ee534dcfd9d2be3a3f9c65a6c5f599b0", // v0
"6d9aa2e029466438d3e4c22530bd071dbe57b549b87370957b28da8ae083f8d6", // key0
"350be52552a65a804a106543ebb7dd046cffae104e4e8b2f18936d564d3c1950", // EntropyInputReseed
"7a3688adb1cfb6c03264e2762ece96bfe4daf9558fabf74d7fff203c08b4dd9f", // AdditionalInputReseed
"433725f6c4b8c662c3b2db4b75f38d86", // v1
"b5953178a900b2fcf052b5cbc1d882ea944da2965e84fef59c4919bb4d5c892d", // key1
"67cf4a56d081c53670f257c25557014cd5e8b0e919aa58f23d6861b10b00ea80", // AdditionalInput1
"2c342b2ab12bd3484e4660b8dd5f85eb", // v2
"b2b9e9f1ffcfd84c050445f93dfad90d6ca240494bbed5d44a0deb38fbaeb751", // key2
"648d4a229198b43f33dd7dd8426650be11c5656adcdf913bb3ee5eb49a2a3892", // AdditionalInput2
"2d819fb9fee38bfc3f15a07ef0e183ff36db5d3184cea1d24e796ba103687415abe6d9f2c59a11931439a3d14f45fc3f4345f331a0675a3477eaf7cd89107e37",
"a9729f842063b9464e74018c0ab30df3", // v3
"770600434fe0af64e045f5530e2b9732da9e3b4c3af342994a4f1f7ee5c4144e", // key3
},
{ // SM4-128, without additional input
true,
sm4.NewCipher,
16,
"2d4c9f46b981c6a0b2b5d8c69391e569ff13851437ebc0fc00d616340252fed5",
"0bf814b411f65ec4866be1abb59d3c32",
"",
"044f9ff3b7e8ad2b60a7b2c05fe6b5b7",
"7fce60b97d8ceb60506bff1d37b1a936",
"93500fae4fa32b86033b7a7bac9d37e710dcc67ca266bc8607d665937766d207",
"",
"8bd44b2e39f8186497f889c73555797d", // v1
"02b9a8f88124bd9cec909e1fd7ec9971", //key1
"",
"fbc91ad876ba3a84588be2f358b9e13c", // v2
"4804b2a1a971ca729abff5bada051cf6", //key2
"",
"e732a524de8ad239aa293ac8ae588f9d",
"ce60250d77048bdbe48ade354b6869f6",
"6788e31ae27aae09a14aed967ce8b219",
},
{ // SM4-128, with additional input
false,
sm4.NewCipher,
16,
"6f60f0f9d486bc23e1223b934e61c0c78ae9232fa2e9a87c6dacd447c3f10e9e",
"401e3f87762fa8a14ab232ccb8480a2f",
"",
"5e8c10afe142dc9c8caf35411b38730a", // v0
"d72aefa9fd527383ad418f6158627feb", // key0
"350be52552a65a804a106543ebb7dd046cffae104e4e8b2f18936d564d3c1950", // EntropyInputReseed
"7a3688adb1cfb6c03264e2762ece96bfe4daf9558fabf74d7fff203c08b4dd9f", // AdditionalInputReseed
"c00836da0fd780cdc81dabec80e344ce", // v1
"f5f3abdeff30df22f4866d83cd96bc1b", // key1
"67cf4a56d081c53670f257c25557014cd5e8b0e919aa58f23d6861b10b00ea80", // AdditionalInput1
"6ddb205ec76567b31a07ee48437acebc", // v2
"5e23cbe8b97065102ca0d87bfd9ae0da", // key2
"648d4a229198b43f33dd7dd8426650be11c5656adcdf913bb3ee5eb49a2a3892", // AdditionalInput2
"b0ac91f148efbdc3570d7e434aba8d24",
"d1f029bb089613d836ddc6fe1d6fb96f", // v3
"8adfe65e9137b18f060ae91e7a6224c1", // key3
},
}
func TestCtrDRBG(t *testing.T) {
for i, test := range ctrtests {
entropyInput, _ := hex.DecodeString(test.entropyInput)
nonce, _ := hex.DecodeString(test.nonce)
personalizationString, _ := hex.DecodeString(test.personalizationString)
v0, _ := hex.DecodeString(test.v0)
key0, _ := hex.DecodeString(test.key0)
hd, err := NewCtrDrbg(test.cipherProvider, test.keyLen, SECURITY_LEVEL_ONE, test.gm, entropyInput, nonce, personalizationString)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(hd.v[:len(v0)], v0) {
t.Errorf("case %v, not same v0 %s", i+1, hex.EncodeToString(hd.v))
}
if !bytes.Equal(hd.key[:len(key0)], key0) {
t.Errorf("case %v, not same key0 %s", i+1, hex.EncodeToString(hd.key))
}
// Reseed
entropyInputReseed, _ := hex.DecodeString(test.entropyInputReseed)
additionalInputReseed, _ := hex.DecodeString(test.additionalInputReseed)
v1, _ := hex.DecodeString(test.v1)
key1, _ := hex.DecodeString(test.key1)
err = hd.Reseed(entropyInputReseed, additionalInputReseed)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(hd.v, v1) {
t.Errorf("case %v, not same v1 %s", i+1, hex.EncodeToString(hd.v))
}
if !bytes.Equal(hd.key, key1) {
t.Errorf("case %v, not same key1 %s", i+1, hex.EncodeToString(hd.key))
}
// Generate 1
returnbits1, _ := hex.DecodeString(test.returnbits1)
v2, _ := hex.DecodeString(test.v2)
key2, _ := hex.DecodeString(test.key2)
output := make([]byte, len(returnbits1))
additionalInput1, _ := hex.DecodeString(test.additionalInput1)
hd.Generate(output, additionalInput1)
if !bytes.Equal(hd.v, v2) {
t.Errorf("case %v, not same v2 %s", i+1, hex.EncodeToString(hd.v))
}
if !bytes.Equal(hd.key, key2) {
t.Errorf("case %v, not same key2 %s", i+1, hex.EncodeToString(hd.key))
}
// Generate 2
v3, _ := hex.DecodeString(test.v3)
key3, _ := hex.DecodeString(test.key3)
additionalInput2, _ := hex.DecodeString(test.additionalInput2)
hd.Generate(output, additionalInput2)
if !bytes.Equal(hd.v[:len(v0)], v3) {
t.Errorf("case %v, not same v3 %s", i+1, hex.EncodeToString(hd.v))
}
if !bytes.Equal(hd.key, key3) {
t.Errorf("case %v, not same key3 %s", i+1, hex.EncodeToString(hd.key))
}
if !bytes.Equal(returnbits1, output) {
t.Errorf("case %v, not expected return bits %s", i+1, hex.EncodeToString(output))
}
}
}
func TestGmCtrDRBG_Validation(t *testing.T) {
entropyInput := make([]byte, 64)
_, err := NewCtrDrbg(sm4.NewCipher, 16, SECURITY_LEVEL_ONE, true, entropyInput[:16], entropyInput[16:24], nil)
if err == nil {
t.Fatalf("expected error here")
}
_, err = NewCtrDrbg(sm4.NewCipher, 16, SECURITY_LEVEL_ONE, true, entropyInput[:32], entropyInput[32:40], nil)
if err == nil {
t.Fatalf("expected error here")
}
hd, err := NewCtrDrbg(sm4.NewCipher, 16, SECURITY_LEVEL_ONE, true, entropyInput[:32], entropyInput[32:48], nil)
if err != nil {
t.Fatal(err)
}
err = hd.Reseed(entropyInput[:16], nil)
if err == nil {
t.Fatalf("expected error here")
}
}