Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F97870745
ECElGamal.java
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Jan 7, 00:23
Size
4 KB
Mime Type
text/x-c
Expires
Thu, Jan 9, 00:23 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
23424285
Attached To
R3229 Genome Privacy - SHCS App
ECElGamal.java
View Options
package
crypto.elgamal
;
import
java.math.BigInteger
;
import
java.security.SecureRandom
;
import
java.util.HashMap
;
import
org.bouncycastle.asn1.nist.NISTNamedCurves
;
import
org.bouncycastle.asn1.x9.X962NamedCurves
;
import
org.bouncycastle.asn1.x9.X9ECParameters
;
import
org.bouncycastle.math.ec.ECPoint
;
public
class
ECElGamal
{
public
static
final
int
PART_SPU
=
1
;
public
static
final
int
PART_MU
=
2
;
//FIXME: fix number of bits (q)?
private
static
final
int
PRIV_KEY_BITLENGTH
=
128
;
//FIXME: depends on the result space
private
static
final
int
DOMAIN_RANGE
=
10000
;
private
X9ECParameters
ecParams
;
private
BigInteger
privKey
;
private
ECPoint
pPubKey
;
private
int
partNumber
;
private
SecureRandom
randomGen
;
private
HashMap
<
ECPoint
,
BigInteger
>
reverseTable
;
public
ECElGamal
()
{
this
(
NISTNamedCurves
.
getByName
(
"P-521"
));
}
public
ECElGamal
(
X9ECParameters
ecParams
)
{
this
.
ecParams
=
ecParams
;
randomGen
=
new
SecureRandom
();
this
.
privKey
=
new
BigInteger
(
PRIV_KEY_BITLENGTH
,
randomGen
);
this
.
pPubKey
=
ecParams
.
getG
().
multiply
(
privKey
);
}
public
ECElGamal
(
X9ECParameters
ecParams
,
BigInteger
privKey
)
{
this
.
ecParams
=
ecParams
;
randomGen
=
new
SecureRandom
();
this
.
privKey
=
privKey
;
this
.
pPubKey
=
ecParams
.
getG
().
multiply
(
privKey
);
}
public
ECElGamal
(
X9ECParameters
ecParams
,
ECPoint
pPubKey
)
{
this
.
ecParams
=
ecParams
;
randomGen
=
new
SecureRandom
();
this
.
pPubKey
=
pPubKey
;
}
public
void
initReverseDLTable
()
{
initReverseDLTable
(
BigInteger
.
valueOf
(
DOMAIN_RANGE
));
}
private
void
initReverseDLTable
(
BigInteger
size
)
{
if
(
reverseTable
!=
null
)
{
System
.
out
.
println
(
"Reverse Discrete Logarithm table exists already!"
);
return
;
}
else
{
reverseTable
=
new
HashMap
<>(
size
.
intValue
());
// XXX: beware of this
BigInteger
i
=
BigInteger
.
ZERO
;
while
(
i
.
compareTo
(
size
)
<
0
)
{
// counter < size
ECPoint
p
=
ecParams
.
getG
().
multiply
(
i
);
reverseTable
.
put
(
p
,
i
);
i
=
i
.
add
(
BigInteger
.
ONE
);
}
}
}
public
boolean
canDecrypt
()
{
//FIXME need modification with threshold encryption
// FIXME obselete now. need canDecrypt and canReverse
return
(
privKey
!=
null
)
&&
(
reverseTable
!=
null
);
}
public
FragmentEncrypted
encrypt
(
BigInteger
msg
)
{
ECPoint
pMsg
=
map
(
msg
);
BigInteger
random
=
new
BigInteger
(
PRIV_KEY_BITLENGTH
,
randomGen
);
ECPoint
R
=
ecParams
.
getG
().
multiply
(
random
);
ECPoint
S
=
pMsg
.
add
(
pPubKey
.
multiply
(
random
));
return
new
FragmentEncrypted
(
R
,
S
);
}
public
BigInteger
decrypt
(
FragmentEncrypted
frag
)
{
if
(!
canDecrypt
())
{
throw
new
UnsupportedOperationException
(
"Private key undefined"
);
}
ECPoint
M
=
frag
.
getS
().
subtract
(
frag
.
getR
().
multiply
(
privKey
));
return
rmap
(
M
);
}
public
FragmentPartial
partialDecrypt
(
FragmentEncrypted
frag
)
{
if
(!
canDecrypt
())
{
throw
new
UnsupportedOperationException
(
"Private key undefined"
);
}
if
(
partNumber
==
0
)
{
throw
new
IllegalStateException
(
"No part number set: unable to partially decrypt"
);
}
ECPoint
T
=
frag
.
getR
().
multiply
(
privKey
);
return
new
FragmentPartial
(
partNumber
,
frag
,
T
);
}
public
BigInteger
fullDecrypt
(
FragmentPartial
fragmentMU
,
FragmentPartial
fragmentSPU
)
{
if
(
!
fragmentMU
.
equalsFragmentEncrypted
(
fragmentSPU
)
)
{
throw
new
IllegalArgumentException
(
"fragments do not have same source encrypted data"
);
}
else
if
(
fragmentMU
.
getPartNumber
()
!=
PART_MU
)
{
throw
new
IllegalArgumentException
(
"MU fragment does not have matching type"
);
}
else
if
(
fragmentSPU
.
getPartNumber
()
!=
PART_SPU
)
{
throw
new
IllegalArgumentException
(
"SPU fragment does not have matching type"
);
}
ECPoint
tMU
=
fragmentMU
.
getT
().
multiply
(
BigInteger
.
valueOf
(
2
));
ECPoint
tSPU
=
fragmentSPU
.
getT
();
ECPoint
F
=
tMU
.
subtract
(
tSPU
);
ECPoint
M
=
fragmentMU
.
getS
().
subtract
(
F
);
return
rmap
(
M
);
}
private
ECPoint
map
(
BigInteger
msg
)
{
if
(
msg
.
compareTo
(
BigInteger
.
valueOf
(
DOMAIN_RANGE
))
>
0
)
{
throw
new
IllegalArgumentException
(
"msg should be less than "
+
DOMAIN_RANGE
);
}
return
ecParams
.
getG
().
multiply
(
msg
);
}
private
BigInteger
rmap
(
ECPoint
p
)
{
BigInteger
m
=
reverseTable
.
get
(
p
);
if
(
m
==
null
)
{
// mapping not indexed. Out of Domain Range.
throw
new
ArrayIndexOutOfBoundsException
(
"Could not find mapping for EC point"
);
}
return
m
;
}
public
X9ECParameters
getECParams
()
{
return
ecParams
;
}
public
void
setPartNumber
(
int
partNumber
)
{
this
.
partNumber
=
partNumber
;
}
public
static
void
main
(
String
[]
args
)
{
ECElGamal
eccegScheme
=
new
ECElGamal
(
NISTNamedCurves
.
getByName
(
"P-384"
));
System
.
out
.
print
(
"Generating table lookup..."
);
eccegScheme
.
initReverseDLTable
();
System
.
out
.
println
(
"[OK]"
);
}
public
static
void
test
()
{
// X9ECParameters params = NISTNamedCurves.getByName("P-384");
X9ECParameters
params
=
NISTNamedCurves
.
getByName
(
"P-521"
);
X9ECParameters
params2
=
X962NamedCurves
.
getByName
(
"c2pnb163v1"
);
System
.
out
.
println
(
"Field size :"
+
params
.
getCurve
().
getFieldSize
());
System
.
out
.
println
(
"n="
+
params
.
getN
());
}
}
Event Timeline
Log In to Comment