import
android.util.Base64
import
kotlinx.coroutines.CancellationException
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
net.sf.ntru.encrypt.EncryptionKeyPair
import
net.sf.ntru.encrypt.EncryptionParameters
import
net.sf.ntru.encrypt.NtruEncrypt
import
net.sf.ntru.exception.NtruException
import
net.sf.ntru.sign.NtruSign
import
net.sf.ntru.sign.SignatureKeyPair
import
net.sf.ntru.sign.SignatureParameters
class
NtruCipher {
companion object {
private
val SIGNATURE_PARAMS = SignatureParameters.APR2011_439_PROD
private
val ENCRYPTION_PARAMS = EncryptionParameters.APR2011_439_FAST
}
private
val ntruEncrypt: NtruEncrypt by lazy { NtruEncrypt(ENCRYPTION_PARAMS) }
private
val ntruSign: NtruSign by lazy { NtruSign(SIGNATURE_PARAMS) }
private
val encKePair: EncryptionKeyPair by lazy {
ntruEncrypt.generateKeyPair()
}
private
val signKeyPair: SignatureKeyPair by lazy {
SignatureKeyPair(Base64.decode(sigKPStr, Base64.DEFAULT))
}
suspend fun encrypt(message: String): Result<ByteArray> = withContext(Dispatchers.Default) {
try
{
Result.success(ntruEncrypt.encrypt(message.toByteArray(), encKePair.
public
))
}
catch
(e: CancellationException) {
throw
e
}
catch
(e: NtruException) {
Result.failure(e)
}
}
suspend fun decrypt(encrypted: ByteArray): Result<ByteArray> =
withContext(Dispatchers.Default) {
try
{
Result.success(ntruEncrypt.decrypt(encrypted, encKePair))
}
catch
(e: CancellationException) {
throw
e
}
catch
(e: NtruException) {
Result.failure(e)
}
}
private
suspend fun verify(message: String): Result<Boolean> =
withContext(Dispatchers.Default) {
val signature = ntruSign.sign(message.toByteArray(), signKeyPair)
try
{
val verified = ntruSign.verify(message.toByteArray(), signature, signKeyPair.
public
)
Result.success(verified)
}
catch
(e: CancellationException) {
throw
e
}
catch
(e: NtruException) {
Result.failure(e)
}
}
}
const
val sigKPStr =
"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"