Skip to content
GitLab
菜单
项目
群组
代码片段
/
帮助
帮助
支持
社区论坛
快捷键
?
提交反馈
登录/注册
切换导航
菜单
打开侧边栏
Heng Wang
Eurocrypto18-AggregateSignatures
提交
4be88b6f
提交
4be88b6f
编辑于
6月 17, 2020
作者:
wang
浏览文件
Finish Basic Functionality
上级
变更
4
Hide whitespace changes
Inline
Side-by-side
BasicSAS.cpp
0 → 100644
浏览文件 @
4be88b6f
#include
"BasicSAS.h"
BasicSAS
::
BasicSAS
(
const
PP
&
pp
)
:
publicParameters
(
pp
),
prng
{},
sk
(
k
+
1
,
Integer
::
Zero
()),
pk
(
k
+
1
,
Integer
::
Zero
()),
ma
{
this
->
publicParameters
.
getN
()}
{}
void
BasicSAS
::
Keygen
()
{
for
(
int
i
=
0
;
i
<=
this
->
k
;
++
i
)
{
sk
[
i
]
=
Integer
{
prng
,
Integer
::
One
(),
this
->
publicParameters
.
getN
()};
pk
[
i
]
=
ma
.
Exponentiate
(
this
->
publicParameters
.
getY
(),
sk
[
i
]);
}
}
Integer
BasicSAS
::
sign
(
const
string
&
msg
,
unsigned
time
)
{
assert
(
time
>=
1
&&
time
<=
this
->
publicParameters
.
getT
());
// The message is L bits which will be broken into k chunks each of l bits
vector
<
Integer
>
msg_frag
{
this
->
dismantleMsg
(
msg
)};
// Now we need to caculate the prime number from public parameters
vector
<
Integer
>
es
(
this
->
publicParameters
.
getT
()
-
1
,
Integer
::
Zero
());
for
(
unsigned
i
=
1
,
ind
=
0
;
i
<=
this
->
publicParameters
.
getT
();
++
i
)
{
if
(
i
!=
time
)
{
es
[
ind
++
]
=
this
->
publicParameters
.
hashToPrime
(
i
);
}
}
// Sign the message
Integer
sigma
{
ma
.
Exponentiate
(
this
->
publicParameters
.
get_g
(),
this
->
sk
.
front
())};
Integer
eMul
{
Integer
::
One
()};
for
(
auto
&
i
:
es
)
{
eMul
*=
i
;
}
for
(
int
i
=
1
;
i
<=
this
->
k
;
++
i
)
{
sigma
=
ma
.
Multiply
(
sigma
,
ma
.
Exponentiate
(
this
->
publicParameters
.
get_g
(),
sk
[
i
]
*
msg_frag
[
i
-
1
]));
}
sigma
=
ma
.
Exponentiate
(
sigma
,
eMul
);
return
sigma
;
}
bool
BasicSAS
::
verify
(
const
string
&
msg
,
unsigned
time
,
const
Integer
&
signautre
)
{
vector
<
Integer
>
msg_frag
{
this
->
dismantleMsg
(
msg
)};
Integer
e_t
{
this
->
publicParameters
.
hashToPrime
(
time
)};
Integer
left
{
ma
.
Exponentiate
(
signautre
,
e_t
)};
Integer
right
{
this
->
pk
.
front
()};
for
(
unsigned
i
=
1
;
i
<=
this
->
k
;
++
i
)
{
right
=
ma
.
Multiply
(
right
,
ma
.
Exponentiate
(
pk
[
i
],
msg_frag
[
i
-
1
]));
}
return
left
==
right
;
}
vector
<
Integer
>
BasicSAS
::
dismantleMsg
(
const
string
&
msg
)
{
// The message is L bits which will be broken into k chunks each of l bits
unsigned
l
=
this
->
L
/
this
->
k
;
SecByteBlock
mB
{(
const
CryptoPP
::
byte
*
)
msg
.
data
(),
msg
.
size
()};
Integer
m
{
mB
,
mB
.
size
()};
// Check the bit size
assert
(
m
.
BitCount
()
<=
this
->
L
);
// The following step is to convert message to chunks of Integers
SecByteBlock
block
{
this
->
L
};
vector
<
SecByteBlock
>
ms
(
this
->
k
,
SecByteBlock
{
l
});
m
.
Encode
(
block
,
this
->
L
);
for
(
unsigned
i
=
0
,
ind
=
0
;
i
<
this
->
L
;
i
+=
l
,
++
ind
)
{
ms
[
ind
].
Assign
(
block
.
BytePtr
()
+
i
,
l
);
}
vector
<
Integer
>
msg_frag
;
for
(
auto
begin
=
ms
.
begin
();
begin
!=
ms
.
end
();
++
begin
)
{
msg_frag
.
push_back
(
Integer
{
*
begin
,
begin
->
size
()});
}
assert
(
msg_frag
.
size
()
==
this
->
k
);
return
msg_frag
;
}
int
main
(
int
argc
,
char
**
argv
)
{
const
unsigned
lambda
=
256
;
const
unsigned
timePeriod
=
10
;
Setup
pp
{
lambda
,
timePeriod
};
BasicSAS
sas
{
pp
};
cout
<<
"Setup Done."
<<
endl
;
cout
<<
pp
.
getN
()
<<
endl
;
sas
.
Keygen
();
string
msg
{
"Hello, World."
};
string
msgFake
{
"Hello."
};
const
unsigned
time
=
2
;
const
unsigned
timeFake
=
3
;
Integer
s
{
sas
.
sign
(
msg
,
time
)};
cout
<<
"Signature: "
<<
s
<<
endl
;
cout
<<
"Verify: "
<<
sas
.
verify
(
msg
,
time
,
s
)
<<
endl
;
cout
<<
"False Verify: "
<<
sas
.
verify
(
msgFake
,
time
,
s
)
<<
endl
;
cout
<<
"False Verify: "
<<
sas
.
verify
(
msg
,
timeFake
,
s
)
<<
endl
;
cout
<<
"False Verify: "
<<
sas
.
verify
(
msg
,
time
,
Integer
::
One
())
<<
endl
;
}
\ No newline at end of file
BasicSAS.h
0 → 100644
浏览文件 @
4be88b6f
#include
"cryptopp/modarith.h"
#include
"Setup.h"
#include
<vector>
#include
<string>
class
Setup
;
using
PP
=
Setup
;
using
std
::
vector
;
using
std
::
string
;
using
CryptoPP
::
ModularArithmetic
;
class
BasicSAS
{
public:
BasicSAS
(
const
PP
&
);
void
Keygen
();
Integer
sign
(
const
string
&
,
unsigned
);
bool
verify
(
const
string
&
,
unsigned
,
const
Integer
&
);
inline
vector
<
Integer
>
BasicSAS
::
publicKey
()
{
return
this
->
pk
;
}
private:
BasicSAS
();
const
unsigned
k
=
4
;
const
unsigned
L
=
1024
;
AutoSeededRandomPool
prng
;
PP
publicParameters
;
vector
<
Integer
>
sk
;
vector
<
Integer
>
pk
;
ModularArithmetic
ma
;
vector
<
Integer
>
dismantleMsg
(
const
string
&
);
};
\ No newline at end of file
Setup.cpp
0 → 100644
浏览文件 @
4be88b6f
#include
"Setup.h"
class
Setup
;
Setup
::
Setup
(
const
Setup
&
s
)
:
Setup
{
s
.
lambda
,
s
.
timePeriod
}
{}
Setup
::
Setup
(
unsigned
lambda
,
unsigned
timePeriod
)
:
lambda
{
lambda
},
timePeriod
{
timePeriod
},
rng
{},
Ks
{
this
->
rng
,
Integer
::
Zero
(),
Integer
::
Power2
(
lambda
+
1
).
Minus
(
Integer
::
One
())},
c
{
this
->
rng
,
Integer
::
Zero
(),
Integer
::
Power2
(
lambda
).
Minus
(
Integer
::
One
())},
T
{
timePeriod
}
{
unsigned
primeBits
=
lambda
/
2
;
Integer
p
,
q
,
subp
,
subq
;
while
(
true
)
{
PrimeAndGenerator
pgP
{
this
->
delta
,
this
->
rng
,
primeBits
};
PrimeAndGenerator
pgQ
{
this
->
delta
,
this
->
rng
,
primeBits
};
Integer
phi
{
pgP
.
SubPrime
()
*
pgQ
.
SubPrime
()
*
Integer
::
Power2
(
2
)};
if
(
phi
.
BitCount
()
==
lambda
)
{
p
=
pgP
.
Prime
();
q
=
pgQ
.
Prime
();
subp
=
pgP
.
SubPrime
();
subq
=
pgQ
.
SubPrime
();
break
;
}
}
PrimeAndGenerator
pgD
{
this
->
delta
,
this
->
rng
,
primeBits
,
primeBits
/
2
};
this
->
e_default
=
pgD
.
Prime
();
this
->
N
=
p
*
q
;
assert
(
N
.
BitCount
()
==
lambda
&&
N
.
BitCount
()
<
lambda
+
1
);
Integer
a
{
this
->
rng
,
Integer
::
One
(),
N
-
Integer
::
One
()};
while
(
!
this
->
isGoodNumber
(
a
,
p
,
q
))
{
a
.
Randomize
(
this
->
rng
,
Integer
::
One
(),
N
-
Integer
::
One
());
}
this
->
g
=
a
.
Squared
().
Modulo
(
N
);
// Now we have the generator of the group of quadratic residues
Integer
E
{
Integer
::
One
()};
for
(
unsigned
t
=
1
;
t
<=
timePeriod
;
++
t
)
{
Integer
e
{
hashToPrime
(
t
)};
E
=
E
*
e
;
primes
.
push_back
(
e
);
}
E
=
E
.
Modulo
(
Integer
{
4
}
*
subp
*
subq
);
this
->
Y
=
ModularExponentiation
(
this
->
g
,
E
,
N
);
}
bool
Setup
::
isGoodNumber
(
const
Integer
&
a
,
const
Integer
&
q
,
const
Integer
&
p
)
{
Integer
aModp
{
a
.
Modulo
(
p
)};
if
(
aModp
.
IsZero
()
||
aModp
.
IsUnit
()
||
aModp
+
Integer
::
One
()
==
p
)
{
return
false
;
}
Integer
aModq
{
a
.
Modulo
(
q
)};
if
(
aModq
.
IsZero
()
||
aModq
.
IsUnit
()
||
aModq
+
Integer
::
One
()
==
q
)
{
return
false
;
}
return
true
;
}
Integer
Setup
::
PRF
(
const
unsigned
&
t
,
const
unsigned
&
i
)
{
Integer
tI
{
t
},
iI
{
i
};
Integer
s
{
iI
+
tI
*
Integer
::
Power2
(
iI
.
BitCount
())
+
this
->
e_default
*
Integer
::
Power2
(
iI
.
BitCount
()
+
tI
.
BitCount
())
+
this
->
c
*
Integer
::
Power2
(
iI
.
BitCount
()
+
tI
.
BitCount
()
+
this
->
e_default
.
BitCount
())
+
this
->
Ks
*
Integer
::
Power2
(
iI
.
BitCount
()
+
tI
.
BitCount
()
+
this
->
e_default
.
BitCount
()
+
this
->
c
.
BitCount
())};
auto
enCodeSize
=
s
.
MinEncodedSize
();
SecByteBlock
seed
{
enCodeSize
};
s
.
Encode
(
seed
,
enCodeSize
);
RandomPool
prng
;
prng
.
IncorporateEntropy
(
seed
,
seed
.
size
());
SecByteBlock
rndBytes
{
this
->
lambda
/
8
-
1
};
prng
.
GenerateBlock
(
rndBytes
,
rndBytes
.
size
());
return
Integer
{
rndBytes
,
rndBytes
.
size
()};
}
Integer
Setup
::
hashToPrime
(
unsigned
&
t
)
{
// The porpose of this step is to ensure the code always get the same probably prime
// Because the IsPrime of CryptoPP is probabilistic test
if
(
this
->
primes
.
size
()
>=
t
)
{
return
this
->
primes
[
t
-
1
];
}
auto
end
=
this
->
lambda
*
(
this
->
lambda
*
this
->
lambda
+
this
->
lambda
);
for
(
auto
i
=
1
;
i
<=
end
;
++
i
)
{
auto
y
=
this
->
PRF
(
t
,
i
);
assert
(
y
.
BitCount
()
<=
this
->
lambda
);
Integer
e
{
Integer
::
Power2
(
this
->
lambda
)
+
this
->
c
.
Xor
(
y
)};
if
(
CryptoPP
::
IsPrime
(
e
))
{
return
e
;
}
}
return
this
->
e_default
;
}
\ No newline at end of file
Setup.h
0 → 100644
浏览文件 @
4be88b6f
#include
"cryptopp/nbtheory.h"
#include
<iostream>
#include
"cryptopp/osrng.h"
#include
<cassert>
#include
<vector>
#include
"cryptopp/integer.h"
using
CryptoPP
::
PrimeAndGenerator
;
using
CryptoPP
::
AutoSeededRandomPool
;
using
CryptoPP
::
Integer
;
using
CryptoPP
::
ModularExponentiation
;
using
CryptoPP
::
SecByteBlock
;
using
CryptoPP
::
RandomPool
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
vector
;
class
Setup
{
public:
Setup
(
unsigned
lambda
,
unsigned
timePeriod
);
Setup
(
const
Setup
&
);
inline
unsigned
getT
();
inline
Integer
getN
();
inline
Integer
get_g
();
inline
Integer
getY
();
inline
Integer
get_e_default
();
inline
Integer
getKs
();
inline
Integer
get_c
();
Integer
hashToPrime
(
unsigned
&
);
private:
unsigned
lambda
;
unsigned
timePeriod
;
const
int
delta
=
1
;
AutoSeededRandomPool
rng
;
// The following three form a key for PRF K=(Ks, c, default_prime)
Integer
e_default
;
Integer
Ks
;
Integer
c
;
unsigned
T
;
Integer
Y
;
Integer
N
;
Integer
g
;
vector
<
Integer
>
primes
;
/**
* Using to find the generator of the group of quadratic residues
* of N=pq, which has q=2q'+1 and p=2p'+1 with both q' and p' are
* primes.
*
* For achieve this, we need to find a number satisfy gcd(a^2+1, N) = 1
* and gcd(a^2-1, N) = 1. Then the generator g=a^2 (mod N).
*
* Reference: https://math.stackexchange.com/questions/167478/how-to-compute-a-generator-of-this-cyclic-quadratic-residue-group
**/
bool
isGoodNumber
(
const
Integer
&
,
const
Integer
&
,
const
Integer
&
);
Integer
PRF
(
const
unsigned
&
,
const
unsigned
&
);
};
inline
unsigned
Setup
::
getT
()
{
return
this
->
T
;}
inline
Integer
Setup
::
get_e_default
()
{
return
this
->
e_default
;}
inline
Integer
Setup
::
getN
()
{
return
this
->
N
;}
inline
Integer
Setup
::
getY
()
{
return
this
->
Y
;}
inline
Integer
Setup
::
get_g
()
{
return
this
->
g
;}
inline
Integer
Setup
::
get_c
()
{
return
this
->
c
;}
inline
Integer
Setup
::
getKs
()
{
return
this
->
Ks
;}
\ No newline at end of file
编辑
预览
支持
Markdown
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录