Skip to content

Commit bc80771

Browse files
committed
feature: pkcs#1 v2.2 emsa_pss_encode + emsa_pss_verify
1 parent 3add360 commit bc80771

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/padding/pkcs_1_v2_2.jl

+43
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,46 @@ function MGF1(mgfSeed::Vector{UInt8}, maskLen:: Integer; hash = SHA.sha1)
6666
end
6767
return T[1:maskLen]
6868
end
69+
70+
function emsa_pss_encode(M::Vector{UInt8}, emBits::Integer; MGF=ToyPublicKeys.MGF1, hash=SHA.sha1, sLen=0)
71+
hLen = hash(UInt8[]) |> length
72+
(emBits >= 8*hLen + 8 * sLen + 9) || error("emBits !>= 8hLen + 8 * sLen + 9") |> throw
73+
emLen = ceil(emBits/8) |> Integer
74+
emLen < hLen + sLen + 2 && error("encoding error") |> throw
75+
length(M) > (big"2" << 60) && error("message too long") |> throw
76+
salt = UInt8[]
77+
if sLen > 0
78+
salt = rand(UInt8, sLen)
79+
end
80+
mHash = hash(M)
81+
MPrime = vcat(zeros(UInt8, 8), mHash, salt)
82+
H = hash(MPrime)
83+
PS = zeros(UInt8, emLen - sLen - hLen - 2)
84+
DB = vcat(PS, ones(UInt8, 1), salt)
85+
dbMask = MGF(H, emLen - hLen - 1)
86+
maskedDB = DB .⊻ dbMask
87+
maskedDB[1] &= 0xFF >> (8 * emLen - emBits)
88+
EM = vcat(maskedDB, H, UInt8[0xbc])
89+
return EM
90+
end
91+
92+
function emsa_pss_verify(M::Vector{UInt8}, EM::Vector{UInt8}, emBits::Integer; MGF=ToyPublicKeys.MGF1, hash=SHA.sha1, sLen=0)
93+
length(M) > (big"2" << 60) && error("inconsistent") |> throw
94+
mHash = hash(M)
95+
hLen = mHash |> length
96+
emLen = ceil(emBits/8) |> Integer
97+
emLen < hLen + sLen + 2 && error("inconsistent") |> throw
98+
EM[end] != 0xbc && error("inconsistent") |> throw
99+
maskedDB = EM[1:emLen - hLen - 1]
100+
H = EM[emLen - hLen:emLen - 1]
101+
(maskedDB[1] & ~(0xFF >> (8 * emLen - emBits))) != 0 && error("inconsistent") |> throw
102+
dbMask = MGF(H, emLen - hLen - 1)
103+
DB = maskedDB .⊻ dbMask
104+
DB[1] &= 0xFF >> (8 * emLen - emBits)
105+
(DB[1:emLen - hLen - sLen - 2] .!= 0) |> any && error("inconsistent") |> throw
106+
DB[emLen - hLen - sLen - 1] != 1 && error("inconsistent") |> throw
107+
salt = DB[end - sLen + 1 : end]
108+
MPrime = MPrime = vcat(zeros(UInt8, 8), mHash, salt)
109+
HPrime = hash(MPrime)
110+
return H == HPrime
111+
end

test/padding.jl

+49
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using SHA
12
@testset "padding/pkcs_1_v1_5" begin
23
test_vector = Vector{UInt8}([1,2,3])
34
Random.seed!(42)
@@ -35,3 +36,51 @@ end
3536
public_key)
3637
@test unpadded == test_vector
3738
end
39+
40+
@testset "emsa_pss_encode" begin
41+
Random.seed!(42)
42+
M = Vector{UInt8}([3,2,1])
43+
sLen = 0
44+
hLen = SHA.sha1(UInt8[]) |> length
45+
emBits = 8 * hLen + 8 * sLen + 9
46+
padded = ToyPublicKeys.emsa_pss_encode(M,
47+
emBits;
48+
sLen=sLen,
49+
hash=SHA.sha1)
50+
@test padded == UInt8[0x00, 0x39, 0xa1, 0xb4, 0x56, 0x60, 0x17, 0xd8, 0x5f, 0xa1, 0x6e, 0xa9, 0xe8, 0xd1, 0xe6, 0x30, 0x5a, 0xbd, 0xa2, 0x75, 0xb9, 0xbc]
51+
end
52+
53+
@testset "emsa_pss_verify" begin
54+
Random.seed!(42)
55+
M = Vector{UInt8}([3,2,1])
56+
hLen = SHA.sha1(UInt8[]) |> length
57+
sLen = 0
58+
emBits = 8 * hLen + 8 * sLen + 9
59+
emLen = ceil(emBits/8) |> Integer
60+
EM = UInt8[0x00, 0x39, 0xa1, 0xb4, 0x56, 0x60, 0x17, 0xd8, 0x5f, 0xa1, 0x6e, 0xa9, 0xe8, 0xd1, 0xe6, 0x30, 0x5a, 0xbd, 0xa2, 0x75, 0xb9, 0xbc]
61+
consistent = ToyPublicKeys.emsa_pss_verify(M,
62+
EM,
63+
emBits;
64+
sLen=sLen,
65+
hash=SHA.sha1)
66+
@test consistent == true
67+
end
68+
69+
@testset "emsa_pss_verify(emsa_pss_encode)" begin
70+
Random.seed!(42)
71+
M = Vector{UInt8}([3,2,1])
72+
hLen = SHA.sha1(UInt8[]) |> length
73+
sLen = 0
74+
emBits = 8 * hLen + 8 * sLen + 9
75+
emLen = ceil(emBits/8) |> Integer
76+
EM = ToyPublicKeys.emsa_pss_encode(M,
77+
emBits;
78+
sLen = sLen,
79+
hash=SHA.sha1)
80+
consistent = ToyPublicKeys.emsa_pss_verify(M,
81+
EM,
82+
emBits;
83+
sLen=sLen,
84+
hash=SHA.sha1)
85+
@test consistent == true
86+
end

0 commit comments

Comments
 (0)