0.5.8-SNAPSHOT: Multikeys
This commit is contained in:
parent
8e652e0421
commit
1191de284e
@ -2,6 +2,7 @@ package net.sergeych.crypto2
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.sergeych.bipack.Unsigned
|
||||||
import net.sergeych.crypto2.Multikey.Companion.allOf
|
import net.sergeych.crypto2.Multikey.Companion.allOf
|
||||||
import net.sergeych.crypto2.Multikey.Companion.allOfMultikeys
|
import net.sergeych.crypto2.Multikey.Companion.allOfMultikeys
|
||||||
import net.sergeych.crypto2.Multikey.Companion.anyOf
|
import net.sergeych.crypto2.Multikey.Companion.anyOf
|
||||||
@ -70,7 +71,11 @@ sealed class Multikey {
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("k")
|
@SerialName("k")
|
||||||
class Keys internal constructor(val requiredMinimum: Int, val validKeys: Set<VerifyingPublicKey>) : Multikey() {
|
class Keys internal constructor(
|
||||||
|
@Unsigned
|
||||||
|
val requiredMinimum: Int,
|
||||||
|
val validKeys: Set<VerifyingPublicKey>
|
||||||
|
) : Multikey() {
|
||||||
override fun check(keys: Iterable<VerifyingPublicKey>): Boolean {
|
override fun check(keys: Iterable<VerifyingPublicKey>): Boolean {
|
||||||
var matches = 0
|
var matches = 0
|
||||||
for( signer in keys ) {
|
for( signer in keys ) {
|
||||||
@ -88,7 +93,11 @@ sealed class Multikey {
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("n")
|
@SerialName("n")
|
||||||
class SomeOf internal constructor(val requiredMinimum: Int,val validKeys: List<Multikey>) : Multikey() {
|
class SomeOf internal constructor(
|
||||||
|
@Unsigned
|
||||||
|
val requiredMinimum: Int,
|
||||||
|
val validKeys: List<Multikey>
|
||||||
|
) : Multikey() {
|
||||||
override fun check(keys: Iterable<VerifyingPublicKey>): Boolean {
|
override fun check(keys: Iterable<VerifyingPublicKey>): Boolean {
|
||||||
var matches = 0
|
var matches = 0
|
||||||
for( k in validKeys ) {
|
for( k in validKeys ) {
|
||||||
|
@ -6,6 +6,7 @@ import kotlinx.serialization.Transient
|
|||||||
import net.sergeych.bipack.BipackDecoder
|
import net.sergeych.bipack.BipackDecoder
|
||||||
import net.sergeych.bipack.BipackEncoder
|
import net.sergeych.bipack.BipackEncoder
|
||||||
import net.sergeych.bipack.decodeFromBipack
|
import net.sergeych.bipack.decodeFromBipack
|
||||||
|
import net.sergeych.utools.pack
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multi-signed data box. Do not use the constructori directly, use [SealedBox.create]
|
* Multi-signed data box. Do not use the constructori directly, use [SealedBox.create]
|
||||||
@ -60,7 +61,7 @@ class SealedBox(
|
|||||||
* Add expiring seal, otherwise use [plus]. Overrides exising seal for [key]
|
* Add expiring seal, otherwise use [plus]. Overrides exising seal for [key]
|
||||||
* if present:
|
* if present:
|
||||||
*/
|
*/
|
||||||
fun addSeal(key: SigningKey, expiresAt: Instant): SealedBox {
|
fun addSeal(key: SigningKey, expiresAt: Instant?): SealedBox {
|
||||||
val filtered = seals.filter { it.publicKey != key.verifyingKey }
|
val filtered = seals.filter { it.publicKey != key.verifyingKey }
|
||||||
return SealedBox(message, filtered + key.seal(message, expiresAt), false)
|
return SealedBox(message, filtered + key.seal(message, expiresAt), false)
|
||||||
}
|
}
|
||||||
@ -78,6 +79,11 @@ class SealedBox(
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun isSealedBy(multikey: Multikey) = multikey.check(signedByKeys)
|
fun isSealedBy(multikey: Multikey) = multikey.check(signedByKeys)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpack bipack-encoded payload
|
||||||
|
*/
|
||||||
|
inline fun <reified T>unpack(): T = BipackDecoder.decode(message)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (seals.isEmpty()) throw IllegalArgumentException("there should be at least one seal")
|
if (seals.isEmpty()) throw IllegalArgumentException("there should be at least one seal")
|
||||||
if (checkOnInit) {
|
if (checkOnInit) {
|
||||||
@ -102,6 +108,19 @@ class SealedBox(
|
|||||||
return SealedBox(data, keys.map { it.seal(data) }, false)
|
return SealedBox(data, keys.map { it.seal(data) }, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance serializing given data with Bipack and some
|
||||||
|
* keys. At least one key is required to disallow providing not-signed
|
||||||
|
* instances, e.g. [SealedBox] is guaranteed to be properly sealed when
|
||||||
|
* successfully instantiated.
|
||||||
|
*
|
||||||
|
* @param payload an object to serialize and sign
|
||||||
|
* @param keys a list of keys to sign with, should be at least one key.
|
||||||
|
* @throws IllegalArgumentException if keys are not specified.
|
||||||
|
*/
|
||||||
|
inline fun <reified T>new(payload: T,vararg keys: SigningKey): SealedBox =
|
||||||
|
create(pack(payload), *keys)
|
||||||
|
|
||||||
inline fun <reified T>encode(value: T, vararg keys: SigningKey): UByteArray =
|
inline fun <reified T>encode(value: T, vararg keys: SigningKey): UByteArray =
|
||||||
create(BipackEncoder.encode(value).toUByteArray(), *keys).encoded
|
create(BipackEncoder.encode(value).toUByteArray(), *keys).encoded
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user