暗号学において、リング署名は、それぞれが鍵を持つユーザー セットの任意のメンバーによって実行できるデジタル署名の一種です。したがって、リング署名で署名されたメッセージは、特定のグループのメンバーによって承認されます。リング署名のセキュリティ特性の 1 つは、セットのメンバーのどの鍵が署名の作成に使用されたかを計算的に判断することが不可能であることです。リング署名はグループ署名に似ていますが、2 つの重要な点で異なります。1 つ目は、個々の署名の匿名性を失効させる方法がないことです。2 つ目は、追加の設定なしで任意のユーザー セットを署名セットとして使用できることです。
リング署名はロン・リベスト、アディ・シャミール、ヤエル・タウマン・カライによって発明され、2001年にASIACRYPTで発表されました。 [ 1 ]リング署名という 名前は、署名アルゴリズムのリングのような構造に由来しています。
この定義には定義に関する情報が不足しています。このセクションでは現在、リング署名の有用な特性について説明していますが、数学的な定義(2022年4月) |
一組のエンティティがそれぞれ公開鍵と秘密鍵のペア ( P 1 , S 1 ), ( P 2 , S 2 ), ..., ( P n , S n ) を持っているとします。パーティi は、入力 ( m , Si , P 1 , ..., P n ) に対して、メッセージmのリング署名 σ を計算できます。σ、 m、および関連する公開鍵P 1 , ..., P nが与えられれば、誰でもリング署名の有効性を確認できます。リング署名が適切に計算されていれば、チェックに合格するはずです。一方、ある集合のメッセージに対して、その集合の秘密鍵を知らずに有効なリング署名を作成することは困難であるはずです。[ 2 ]

原論文では、リベスト、シャミール、タウマンはリング署名を秘密漏洩の手段として説明しました。例えば、リング署名は「ホワイトハウスの高官」による匿名署名を提供し、どの高官がメッセージに署名したかを明らかにすることなく提供することができます。リング署名は匿名性を失効させることができず、また、リング署名のグループを即興で作成できるため、この用途に適しています。
原論文でも説明されているもう一つの応用は、否認可能署名です。この場合、メッセージの送信者と受信者がリング署名のグループを形成します。この場合、署名は受信者にとって有効ですが、それ以外の人にとっては、受信者と送信者のどちらが実際の署名者であるかは不明です。したがって、このような署名は説得力がありますが、意図した受信者以外には転送できません。
さまざまな前提に基づき、新しい機能を導入したさまざまな作品がありました。
提案されているアルゴリズムのほとんどは、出力サイズが漸近的である。つまり、結果として得られる署名のサイズは、入力サイズ(公開鍵の数)に比例して増加する。つまり、このような方式は、入力サイズが十分に大きい実際のユースケース(例えば、数百万人の参加者がいる電子投票など)には実用的ではない。しかし、入力サイズの中央値が比較的小さいアプリケーションでは、このような推定値は許容できる可能性がある。CryptoNoteは、送信者の追跡不可能性を実現するために、藤崎と鈴木によるリング署名方式[ 5 ]をP2P決済に 実装している。
最近、より効率的なアルゴリズムが登場しています。署名のサイズが線形以下である方式[ 6 ]や、署名のサイズが一定である方式[ 7 ]があります。
原論文では、 RSAベースのリング署名方式と、Rabinベースの方式について説明されています。これらの論文では、鍵、初期値、および任意の値のリストを受け取る鍵付き「結合関数」が定義されています。は と定義され、ここではトラップドア関数(つまり、RSAベースのリング署名の場合はRSA公開鍵)です。
この関数は環方程式と呼ばれ、以下のように定義されます。この方程式は対称暗号化関数に基づいています。
出力は単一の値で、この値は と等しくなるように強制されます。この方程式は、少なくとも1つの、そして拡張して を自由に選択できる 限り、解くことができます。RSAの仮定のもとでは、これはトラップドア関数の逆関数(つまり秘密鍵)の少なくとも1つを知っていることを意味します。なぜなら だからです。
リング署名の生成には6つのステップがあります。平文は、リングの公開鍵はで表されます。
署名の検証には 3 つのステップがあります。
RSAを使用した元の論文のPython実装を以下に示します。サードパーティ製モジュール PyCryptodome が必要です。
osをインポート、 hashlibをインポート、 randomをインポート、 Crypto.PublicKey.RSAをインポートfunctoolsをインポートするクラスRing : """RSA 実装。"""def __init__ ( self , k , L : int = 1024 ) -> None : self . k = k self . l = L self . n = len ( k ) self . q = 1 << ( L - 1 )def sign_message ( self , m : str , z : int ): """メッセージに署名します。""" self . _permut ( m ) s = [ None ] * self . n u = random . randint ( 0 , self . q ) c = v = self . _E ( u )first_range = list ( range ( z + 1 , self.n ) ) second_range = list ( range ( z ) ) whole_range = first_range + second_rangei が全範囲にわたる場合: s [ i ] = random . randint ( 0 , self . q ) e = self . _g ( s [ i ] , self . k [ i ] . e , self . k [ i ] . n ) v = self . _E ( v ^ e ) if ( i + 1 ) % self . n == 0 : c = vs [ z ] = self . _g ( v ^ u , self . k [ z ] . d , self . k [ z ] . n )を返す[ c ] + sdef verify_message ( self , m : str , X ) -> bool : """メッセージを検証します。""" self . _permut ( m )def _f ( i ) : self._g ( X [ i + 1 ] , self.k [ i ] .e , self.k [ i ] .n )を返すy = map ( _f , range ( len ( X ) - 1 )) y = list ( y )def _g ( x , i ): self . _E ( x ^ y [ i ] )を返しますr = functools.reduce ( _g , range ( self.n ) , X [ 0 ] )戻り値r == X [ 0 ]def _permut ( self , m ): msg = m . encode ( "utf-8" ) self . p = int ( hashlib . sha1 ( msg ) . hexdigest (), 16 )def _E ( self , x ): msg = f " { x }{ self . p } " . encode ( "utf-8" ) return int ( hashlib . sha1 ( msg ) . hexdigest (), 16 )def _g ( self , x , e , n ): q , r = divmod ( x , n ) if (( q + 1 ) * n ) <= (( 1 << self . l ) - 1 ): result = q * n + pow ( r , e , n ) else : result = x return result4 人のユーザーのリング内の 2 つのメッセージに署名して検証するには:
サイズ= 4 msg1 、msg2 = "hello" 、"world!"def _rn ( _ ) : Crypto.PublicKey.RSA.generate ( 1024 , os.urandom )を返すkey = map ( _rn , range ( size )) key = list ( key )r =リング(キー)i がrange ( size )の場合: signature_1 = r . sign_message ( msg1 , i ) signature_2 = r . sign_message ( msg2 , i ) assert r . verify_message ( msg1 , signature_1 )かつr . verify_message ( msg2 , signature_2 )であり、 r . verify_message ( msg1 , signature_2 )ではないMonero [ 8 ]や他のいくつかの暗号通貨はこの技術を使用しています。
この記事には、CC BY-SA 4.0ライセンスに基づいて利用可能なテキストが組み込まれています。
{{cite book}}:|journal=無視されました (ヘルプ)