(57)【要約】  本発明に係るプログラム難読化装置は、対象プログラムを複数のブロックに分割し、ブロック間の入出力関係に応じて配置するプログラム命令を決定することで、秘密情報の値を算出するプログラム命令を様々な位置に拡散して配置できるようにしたものである。具体的には、ブロック間で引き継ぐ秘密情報算出用の変数について、ブロックから出る時の値と次のブロックに入る時の値とを揃え、各ブロックから出力される時点での値が次のブロックの入力として期待される値となるような範囲で、各ブロックにランダムな変数変換命令を追加している。
2007091558.tif 000002
【特許請求の範囲】
【請求項１】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とするプログラム難読化装置。
【請求項２】
前記対象プログラムは、秘密情報を含み、
前記プログラム難読化装置は、更に、前記対象プログラムから、特定変数の値に基づいて前記秘密情報を求める命令を含むブロックを秘密ブロックとして特定するブロック特定手段を備え、
前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられており、
前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項３】
前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックが複数ある場合には、全ての当該ブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項４】
前記生成手段は、更に、前記秘密ブロックの前に実行され得るブロックに、当該ブロックの入口の属性に応じた特定変数の値から、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項５】
前記プログラム難読化装置は、更に、前記対象プログラムに含まれない変数を追加する変数追加手段を備え、
前記特定変数は、前記変数追加手段で追加された変数である
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項６】
ブロックの入口または出口の属性に対応付けられている特定変数の値は複数あり、
前記生成手段は、特定変数が、ブロックの入口の属性に応じた特定変数のいずれかの値から当該ブロックの出口の属性に応じたいずれかの値になるようにする1又は複数の命令を付加する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項７】
前記特定変数は、複数あり、
前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項８】
前記属性には、それぞれ所定の演算が対応付けられており、
前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項９】
前記属性には、それぞれ複数の特定変数の値の入れ替えが対応付けられており、
前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える処理を行う命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える処理を行う命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１０】
前記属性には、それぞれ特定変数と所定の演算とが対応付けられており、
前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような処理を行う命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような処理を行う命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１１】
前記プログラム難読化装置は、更に、ブロックを暗号化する暗号化手段を備え、
前記属性には、それぞれ暗号鍵が対応付けられており、
前記生成手段は、ブロックの出口の属性に対応付けられている暗号鍵で、当該ブロックの出口から実行制御が遷移する他のブロックを復号する処理を行う1又は複数の命令を付加し、前記1又は複数の命令を付加したブロックを、前記暗号化手段に当該ブロックの入口の属性に対応付けられている暗号鍵で暗号化させて、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１２】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成される命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を、全ての入口からの実行制御が通る部分に付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とするプログラム難読化装置。
【請求項１３】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定する属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備え、
前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられ、複数のブロックから実行制御が遷移してくるブロックの入口の属性には、遷移元の全てのブロックの出口の属性に対応付けられている値が対応付けられており、
前記生成手段は、１又は複数のブロックに、特定変数が、ブロックの入口の属性に応じた特定変数の値のうちの何れの値からも当該ブロックの出口の属性に応じた値になるようにする処理を行う１又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とするプログラム難読化装置。
【請求項１４】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置において用いられる難読化方法であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定ステップと、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成ステップと
を備えることを特徴とするプログラム難読化方法。
【請求項１５】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置に難読化処理を行わせるコンピュータプログラムであって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定ステップと、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成ステップと
を備えることを特徴とするコンピュータプログラム。
【請求項１６】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置で使用される集積回路であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とする集積回路。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はソフトウェアプロテクションに関するものであり、特に、プログラムの難読化に関する。
【背景技術】
【０００２】
ソフトウェアプロテクションとは、ソフトウェアを改竄、解析、コピー等されることから守ること、すなわち、ソフトウェアの機密性を保持することをいう。
例えば、コピー防止用に、映像コンテンツ等を暗号化する技術がある。しかし、暗号化のプログラムは、秘密情報である暗号鍵を用いて処理を行っており、処理が解析されて暗号鍵が不正解析者に奪われると、暗号化されたコンテンツが復号され、コンテンツが自由に利用できることとなってしまう。【０００３】
また、画像にウォーターマークを埋め込み、コピーを制御する技術がある。しかし、このようなウォーターマークの検出を行うプログラムの処理／アルゴリズムが不正解析者によって解析されると、その解析結果を元に画像に埋め込まれたウォーターマークを除去するツールを作成される恐れがある。すなわち、画像データへのコピー制御が利かなくなり、自由に元の画像のコピーが出来ることとなってしまう。【０００４】
このように、ソフトウェアの機密性が保持できなくなることは権利者の保護に欠け、商業的にも損失が大きいなど不都合が多いことから、プログラムの解析を困難にする技術が要望されている。
このような要望に対し、例えば、非特許文献１には、プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換し、さらに、そのプログラム命令をプログラム中の様々な場所に拡散することで解析を困難にする手法が述べられている。【０００５】
このようなプログラムに含まれる処理を複雑にすること、すなわち、プログラムの難読化は、プログラムの解析に必要な時間を長くすることとなり、結果として、プログラムに含まれる秘密情報の解析を防ぐことが可能になるという効果がある。
【非特許文献１】鴨志田、松本、井上、「耐タンパーソフトウェアの構成手法に関する考察」、ＩＳＥＣ９７−５９
【発明の開示】
【発明が解決しようとする課題】
【０００６】
しかし、このようなプログラムの難読化の手法は、そのプログラムの制御構造によっては複雑にし難い場合がある。
すなわち、分岐やループを多く含む制御構造が複雑なプログラムでは、秘密情報を使用する箇所に至るルートが複数あることとなるが、実行時にどのルートを通ったとしても秘密情報の算出結果が同一でなければならないという制限があるからである。【０００７】
言い換えれば、秘密情報を算出するための処理は、実行時には必ず通るルートにしか配置できないこととなる。
この場合、不正解析者はこのような箇所、例えば、分岐のないプログラムの入口などを重点的に解析することにより、比較的容易に秘密情報を得ることができてしまうことになる。【０００８】
そこで、本発明は、制御構造が複雑なプログラムであっても、処理を複雑にする為のプログラム命令を、広範囲に拡散して配置したプログラムを生成するプログラム難読化装置の提供を目的とする。
【課題を解決するための手段】
【０００９】
上記課題を解決する為に、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備えることを特徴とする。【００１０】
なお、実行制御とは、プログラム実行時に実行され得る複数ルートの選択制御をいう。
【発明の効果】
【００１１】
本発明に係るプログラム難読化装置は、上述の構成を備えることにより、ブロックの出口属性と、そのブロックから実行制御が遷移する遷移先ブロックの入口属性とは同一の属性が設定されることとなり、これらのブロック間で引き継がれる処理の内容は、遷移先ブロックの予定した処理の内容であることが保障される。
従って、遷移先ブロックでは、予定した処理の内容に基づいて、自ブロックの処理を行うことが可能となる。【００１２】
また、前記対象プログラムは、秘密情報を含み、前記プログラム難読化装置は、更に、前記対象プログラムから、特定変数の値に基づいて前記秘密情報を求める命令を含むブロックを秘密ブロックとして特定するブロック特定手段を備え、前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられており、前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。【００１３】
これにより、ブロックの出口属性と、そのブロックから実行制御が遷移する遷移先ブロックの入口属性とは同一の属性が設定されることとなり、これらのブロック間で受け渡される特定変数の値は、遷移先ブロックの予定した値であることが保障される。特定変数が属性に応じて決まるからである。
従って、秘密ブロックに実行が遷移する前のブロック内に、特定変数を使用したいかなるプログラム命令を追加したとしても、係るブロックの出口において特定変数が出口属性に応じた値となるならば、秘密ブロックでは、特定変数を用いて秘密情報を求めることが可能となる。【００１４】
言い換えれば、秘密情報を特定変数から求めるので、秘密情報が直接プログラムの中に現れることが無くなる上、秘密情報を求める式などが秘密情報の位置から離れるので、秘密情報の位置を見つけることが難くなり、結果として、秘密情報が奪われることを回避できる可能性が高くなる。
また、前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックが複数ある場合には、全ての当該ブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。【００１５】
これにより、実行時にいずれのルートを通ったとしても、秘密ブロックの入口では特定変数は予定した値となるので、秘密ブロックでは、特定変数を用いて秘密情報を求めることが可能となる。
また、前記生成手段は、更に、前記秘密ブロックの前に実行され得るブロックに、当該ブロックの入口の属性に応じた特定変数の値から、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。【００１６】
これにより、連続して実行されうるブロック同士は、互いに属性を共有し、属性に応じた変換を行うので、全てのブロックに、難読化のためのプログラム命令を付加することできるようになる。
言い換えれば、全てのブロック内に、特定変数を使用したいかなるプログラム命令を追加したとしても、ブロックの出口において特定変数が出口属性に応じた値となるならば、各ブロックでは、入口属性に応じて変換を相殺する処理を加えることができ、難読化前の処理結果を保証することが可能となる。【００１７】
すなわち、制御構造が複雑なプログラムであっても、全てのブロック内に、プログラム命令を追加することができ、プログラムの解析を困難にすることが出来るようになる。
つまり、従来技術では困難であった複雑な制御構造に対する処理の複雑化が可能となる。
本発明では、少なくともデバッガ等でプログラムの実行手順を強制的に変えるなどを行わないような実行時（以下、「正常系での実行時」という。）には、ブロックに遷移してくる前に加えられた変換を相殺する機能を、そのブロック内に追加することができる。実行制御が遷移するブロック間では属性を共有するため、入口属性に応じた変換が加えられていることが確実だからである。【００１８】
このため、少なくとも正常系での実行時には、ブロック内でのプログラムの実行結果が変わらないことが保証されるので、付加されたプログラム命令による難読化はプログラムの制御構造に関わらず、プログラム中の多様な箇所に施すことができるのである。
ループを例に挙げると、ループを何周回ることとなっても難読化により付加された処理の影響はループの内部で相殺されるため、ループ箇所から出力される結果は難読化前と同一となる。すなわち、難読化前後でプログラムの出力結果は変化しない。【００１９】
従って、従来技術では難読化の前後でプログラムの出力結果を同一とするために処理の複雑化を行う箇所を制限していたのに対し、本発明ではこのような制限のない処理の複雑化が可能となる。
また、前記プログラム難読化装置は、更に、前記対象プログラムに含まれない変数を追加する変数追加手段を備え、前記特定変数は、前記変数追加手段で追加された変数であることとしてもよい。【００２０】
これにより、難読化前のプログラムでは実行使用されない変数を用いて、難読化後プログラムを生成できるので、本来のプログラムの実行に影響を与えずに難読化が可能となり、秘密情報を守る事が出来るようになる。
また、ブロックの入口または出口の属性に対応付けられている特定変数の値は複数あり、前記生成手段は、特定変数が、ブロックの入口の属性に応じた特定変数のいずれかの値から当該ブロックの出口の属性に応じたいずれかの値になるようにする1又は複数の命令を付加することとしてもよい。【００２１】
これにより、ブロックの入口における特定変数の値が１つではなくなるので、デバッガ等を用いたプログラム実行中の解析をより困難とすることができるようになる。
また、前記特定変数は、複数あり、前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える命令を付加し、前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える命令を付加して、難読化プログラムを生成することとしてもよい。【００２２】
これにより、特定変数の役割がブロック毎に異なることとできるので、プログラムの解析をより困難とすることができるようになる。
また、前記属性には、それぞれ所定の演算が対応付けられており、前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような命令を付加し、前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような命令を付加して、難読化プログラムを生成することとしてもよい。【００２３】
これにより、特定変数の値がブロック毎に異なることとできるので、プログラムの解析をより困難とすることができるようになる。
また、前記プログラム難読化装置は、更に、ブロックを暗号化する暗号化手段を備え、前記属性には、それぞれ暗号鍵が対応付けられており、前記生成手段は、ブロックの出口の属性に対応付けられている暗号鍵で、当該ブロックの出口から実行制御が遷移する他のブロックを復号する処理を行う1又は複数の命令を付加し、前記1又は複数の命令を付加したブロックを、前記暗号化手段に当該ブロックの入口の属性に対応付けられている暗号鍵で暗号化させて、難読化プログラムを生成することとしてもよい。【００２４】
これにより、ブロック毎に異なる鍵で暗号化することができるので、プログラムの解析をより困難とすることができるようになる。
また、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成される命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を、全ての入口からの実行制御が通る部分に付加し、難読化プログラムを生成する生成手段とを備えることとしてもよい。【００２５】
これにより、ブロックをより大きなブロックとしたとしても難読化をすることができるので、難読化にかかる処理速度を短縮することができるようになる。
また、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定する属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備え、前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられ、複数のブロックから実行制御が遷移してくるブロックの入口の属性には、遷移元の全てのブロックの出口の属性に対応付けられている値が対応付けられており、前記生成手段は、１又は複数のブロックに、特定変数が、ブロックの入口の属性に応じた特定変数の値のうちの何れの値からも当該ブロックの出口の属性に応じた値になるようにする処理を行う１又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。【００２６】
これにより、複数ブロックから１つのブロックに実行制御が遷移する場合に、実行制御が遷移する元のブロックの出口属性を全てのブロックで同じとしなくてもよいので、これらブロックの出口における特定変数の値が異なることとなり、プログラムの解析をより困難とすることができるようになる。
【図面の簡単な説明】
【００２７】
【図１】本発明にかかるプログラム難読化装置のコンピューティングシステムの例である。
【図２】プログラム難読化装置１０００の構成例を示すブロック図である。
【図３】難読化の対象プログラム２０００の例を示す図である。
【図４】対象プログラムを難読化した後の難読化プログラム３０００の例を示す図である。
【図５】プログラム難読化装置１０００の難読化処理を表すフローチャートである。
【図６】追加変数が追加された対象プログラム２１００を示す図である。
【図７】ブロック分割部１２００が対象プログラム２１００から生成した基本ブロックであるブロックＢ１〜ブロックＢ５を示す図である。
【図８】対象プログラム２１００のコントロールフローを示す図である。
【図９】属性情報割当表生成部１３２０が生成する属性情報割当表１８００の生成過程と、構成及び内容の例を示す図である。
【図１０】属性情報割当表生成処理を表すフローチャートである。
【図１１】各ブロックの入口と出口に設定された属性を示した、コントロールフローである。
【図１２】写像対応表１９００の構成および内容の例を示す図である。
【図１３】ブロックＢ１〜ブロックＢ５を、ブロック変換部１４００が変換して生成した変換後ブロックを示す図である。
【図１４】変換後の秘密ブロックを含む難読化後プログラム３０００を示す図である。
【図１５】実施形態２の写像対応表４９００の構成および内容の例を示す図である。
【図１６】実施形態２にかかるプログラム難読化装置４０００の構成例を示すブロック図である。
【図１７】ブロック変換部４４００によって変換して生成した変換後ブロックＢ２を示す図である。
【図１８】ブロックＢ２の入口と出口での変換を示す図である。
【図１９】プログラム命令群Ｇ＿２＿４による置換えを示す図である。
【図２０】実施形態３の写像対応表５９００の構成および内容の例を示す図である。
【図２１】実施形態３にかかるプログラム難読化装置５０００の構成例を示すブロック図である。
【図２２】ブロック変換手段５４００によって変換して生成した変換後ブロックＢ２を示す図である。
【図２３】実施形態４の写像対応表６９００の構成および内容の例を示す図である。
【図２４】実施形態４にかかるプログラム難読化装置６０００の構成例を示すブロック図である。
【図２５】実施形態４の変換後ブロックを示す図である。
【図２６】ブロック変換部の処理を示すフローチャートである。
【図２７】従来の難読化方法の一例を示す概念図である。
【図２８】難読化前のオリジナルプログラム９１００を示す図である。
【図２９】オリジナルプログラム９１００のコントロールフローを示す図である。
【図３０】秘密情報を算出するプログラム命令を配置した難読化後のプログラムのコントロールフローを示す図である。
【図３１】秘密情報を算出するプログラム命令を拡散した難読化後のプログラムのコントロールフローを示す図である。
【符号の説明】
【００２８】
１０    コンピューティングシステム
１０００  ４０００  ５０００    プログラム難読化装置
１１００    変数追加部
１２００    プログラム分割部
１３００    写像情報生成部
１３１０    コントロールフロー生成部
１３２０    属性情報割当表生成部
１３３０    写像対応表生成部
１４００    ブロック変換部
１５００    秘密ブロック変換部
１８００    属性情報割当表
１９００  ４９００  ５９００  ６９００    写像対応表
２０００  ２１００    対象プログラム
３０００    難読化プログラム
９１００    オリジナルプログラム
【発明を実施するための最良の形態】
【００２９】
＜実施形態１＞
＜概要＞
本発明に係るプログラム難読化装置は、分岐やループを多く含む制御構造が複雑なプログラムであっても、秘密情報を使用する箇所に至る全てのルート上に、処理を複雑にする為のプログラム命令を配置したプログラムを生成することができるものである。【００３０】
本発明の説明の前に、図２８〜図３１を用いて、従来のプログラム難読化について簡単に説明する。従来のプログラム難読化の手法とその課題についての詳細は、後に説明する。
＜従来のプログラム難読化＞
図２８は難読化前のオリジナルプログラム９１００を示す図であり、プログラム命令群９１１０から成る。秘密情報は、プログラム命令９１０１の「１２３」であるとする。【００３１】
図２９は、ブロック９１１１〜ブロック９１１５から成るオリジナルプログラム９１００のコントロールフローを示す図である。また、図３０および図３１は、秘密情報を算出するプログラム命令を配置した難読化後のプログラムのコントロールフローを示す図であり、それぞれブロック９２１１〜ブロック９２１５、ブロック９３１１〜ブロック９３１５から成る。【００３２】
図３０では、オリジナルプログラム９１００に新しい変数「ｃ」を追加し（ブロック９２１１下線部分参照）、追加した変数「ｃ」を用いて秘密情報「１２３」を算出する処理を追加し、秘密情報「１２３」を「ｃ」に置換える（ブロック９２１５下線部分参照）ことで難読化プログラムを生成している。
図３１では、図３０で追加したプログラム命令をプログラム中の様々な位置に拡散したプログラムを示している。【００３３】
ここでは、このプログラム命令は、条件分岐の片側に移動することはできず、また、ループの中身に入れることもできない。秘密情報「１２３」を置き換えた「ｃ」の値が「１２３」と異なる値となってしまうからである。
よって、本プログラム例では「ｃ」の値が最終的に「１２３」となることを保証するために、プログラム命令はブロック９３１１に移動することとなる。【００３４】
このように、従来手法では、分岐やループを含むプログラムでは、プログラム命令を移動可能な位置は少なく、結果として、プログラム命令は十分に拡散されずに特定の箇所、すなわち、プログラム命令の拡散が困難な箇所以外の箇所（分岐やループ等に影響を受けない箇所）に集中してしまう。従って、このような特定の箇所を重点的に解析することにより、秘密情報を算出するプログラム命令群を比較的容易に見つけ出すことができてしまう。【００３５】
本発明に係るプログラム難読化装置は、従来ではプログラム命令の拡散が困難とされていた箇所にも、プログラム命令を配置できるようにしたものである。
以下、本発明の実施形態のプログラム難読化装置について説明する。
本実施形態は、秘密情報を、複数のプログラム命令を実行することによって算出されるように変換する難読化の一例であり、難読化前のプログラム（以下、「対象プログラム」という。）に新たな変数を追加し、秘密情報をかかる変数から算出する式に置き換えて、そこに至る式を広範囲に配置して難読化したプログラム（以下、「難読化プログラム」という。）を生成するものである。【００３６】
＜構成＞
図１は、本発明にかかるプログラム難読化装置のコンピューティングシステムの例である。
コンピューティングシステム１０は、汎用コンピュータ２０、プログラム等を表示するためのディスプレイ１１、キーボード等からユーザの指示を受け付けて処理を行う入力装置１２、及び、プログラム等を記憶する外部メモリ１３で構成される。コンピュータ２０は、入出力を管理するＩ／Ｏ部２１、演算を行うＣＰＵ（Central Processing Unit）２２及びメモリ２３を含み、通常のコンピュータの機能を有する。【００３７】
本発明にかかるプログラム難読化を実行するための難読化プログラムは、メモリ２３や外部メモリ１３に記憶され、ＣＰＵ２２によって実行されることで、難読化の処理を実現する。対象プログラムは、外部メモリ１３から適時Ｉ／Ｏ部２１を介して読み込まれ、難読化が行われ、難読化プログラムは、Ｉ／Ｏ部２１を介して外部メモリ１３に書き出される。【００３８】
以下、図２を用いて、本発明にかかるプログラム難読化装置１０００の構成を説明する。
図２は、プログラム難読化装置１０００の構成例を示すブロック図であり、プログラム難読化装置１０００は、変数追加部１１００、プログラム分割部１２００、写像情報生成部１３００、ブロック変換部１４００、および、秘密ブロック変換部１５００から構成される。また、装置外部から対象プログラム２０００を読み込む入力部（図示しない。）と、難読化プログラム３０００を出力する出力部（図示しない。）を備える。【００３９】
対象プログラム２０００は、入力部によって読み込まれ、変数追加部１１００、プログラム分割部１２００、写像情報生成部１３００、ブロック変換部１４００、秘密ブロック変換部１５００によって順に処理され、難読化プログラム３０００が出力部によって出力される。
図３は、難読化の対象プログラム２０００の例を示す図であり、図４は、対象プログラムを難読化した後の難読化プログラム３０００の例を示す図である。【００４０】
以下、各機能部について簡単に説明し、図３〜図１３を用い、具体例を交えて詳細に説明する。
まず、変数追加部１１００は、対象プログラム２０００に、対象プログラム２０００で使用されていない新たな変数（以下、「追加変数」と言う。）を追加する機能を有する。
次に、プログラム分割部１２００は、対象プログラムを１以上のプログラム命令からなる複数のブロックに分割する機能を有する。【００４１】
写像情報生成部１３００は、追加変数をある値に対応させる写像を生成する機能を有し、コントロールフロー生成部１３１０、属性情報割当表生成部１３２０、及び、写像対応表生成部１３３０で構成される。
コントロールフロー生成部１３１０は、対象プログラムのコントロールフローを生成する機能を有し、属性情報割当表生成部１３２０は、コントロールフローを参照して、ブロックの入口と出口とに属性を割り当てて、属性情報割当表を生成する機能を有する。【００４２】
また、写像対応表生成部１３３０は、属性情報割当表の属性ごとに写像を決定し、写像対応表を生成する機能を有する。
尚、属性情報割当表および写像対応表については、図９、図１２を用いて後で説明する。
ブロック変換部１４００は、写像情報生成部１３００で生成した写像に基づいて、各ブロックに追加変数の値を変換するプログラム命令を追加等する機能を有する。【００４３】
秘密ブロック変換部１５００は、秘密情報を含むブロック（以下、「秘密ブロック」という。）に、追加変数を用いて秘密情報を算出するプログラム命令を追加等する機能を有する。
＜動作＞
図５は、プログラム難読化装置１０００の難読化処理を表すフローチャートである。本図を用いて、対象プログラム２０００から難読化プログラム３０００を生成する処理を説明する。その際、各機能部の詳細な機能も併せて説明する。尚、点線の矩形は、点線矩形内の処理を行う各機能部を示している。【００４４】
対象プログラム２０００は、関数ｆｕｎｃを含み、関数ｆｕｎｃは変数ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃを入力として、プログラム命令群２０１０の処理を行い、変数ｐｍ＿ｂを出力する。また、プログラム命令２００１の「１２３」が秘密情報であるとする（図３参照）。
難読化プログラム３０００は、対象プログラム２０００に複数のプログラム命令が追加され、プログラム命令３００１では、秘密情報「１２３」が式「３＊ｐｍ＿０＋４＊ｐｍ＿１−４０」に変換されている（図４参照）。【００４５】
以下、図５のフローチャートに沿って、難読化処理を説明する。
まず、対象プログラム２０００を入力部が、内部の作業メモリに読み込む（ステップＳ１１０）。
＜変数追加部１１００の処理＞
次に、変数追加部１１００が、読み込まれた対象プログラム２０００に変数を追加する（ステップＳ１２０）。【００４６】
図６に、追加変数が追加された対象プログラム２１００を示す。
本実施形態では、「ｐｍ＿０」と「ｐｍ＿１」の２つの変数を追加するものとする。
変数追加部１１００は、追加変数「ｐｍ＿０」「ｐｍ＿１」の初期値をランダムに決定し、ここでは、それぞれ「０」「１」と決定し、追加変数「ｐｍ＿０」「ｐｍ＿１」の変数宣言を対象プログラム２０００に追加する。【００４７】
変数宣言部２１１０が、このプログラムに追加された追加変数「ｐｍ＿０」「ｐｍ＿１」の変数宣言である。
なお、追加する変数の数、追加する変数の名前、変数の型は固定のものであっても、ユーザによって入力装置１２から入力されるものであっても、ランダムに決定したものであっても構わない。また、追加変数は配列とする構成であってもよい。【００４８】
また、本実施形態では、変数宣言が必要なプログラミング言語であるＣ言語の場合について説明しているが、追加変数の定義方法等は、プログラム言語に応じたものとなる（以下、同様）。例えば、変数宣言を必要としないＢＡＳＩＣのような言語では、変数宣言を必要としないので、初期値の設定のみを記述すればよい。
＜プログラム分割部１２００の処理＞
変数追加部１１００は、追加変数を追加した対象プログラム２１００を、プログラム分割部１２００に渡し、プログラム分割部１２００は、対象プログラム２１００のうちのプログラム命令群２０１０を分割して、複数の基本ブロックを生成する（ステップＳ１３０）。【００４９】
図７に、ブロック分割部１２００が対象プログラム２１００から生成した基本ブロックであるブロックＢ１〜ブロックＢ５を示す。
ここで、基本ブロックとは、１以上のプログラム命令からなるプログラム命令群であって、プログラム命令群の先頭以外では合流せず、プログラム命令群の最後以外では分岐しないプログラム命令群である。【００５０】
より詳細には、基本ブロックを生成する場合、まず、次の３つのプログラム命令のいずれかをブロックの開始プログラム命令とする。１つ目は、プログラムの入口のプログラム命令（プログラムの一番最初に実行されるプログラム命令）、２つ目は、処理が合流するプログラム命令、例えば、Ｌａｂｅｌ文である。３つ目は、分岐となるプログラム命令、例えば、ｇｏｔｏ文の次のプログラム命令である。【００５１】
次に、終了プログラム命令として、次の３つのプログラム命令のいずれかを決める。１つ目は、開始命令プログラムの次に処理が合流するプログラム命令の一つ前のプログラム命令、２つ目は、プログラムの出口の命令（プログラムの一番最後に実行される命令）、３つ目は、分岐となるプログラム命令である。
開始プログラム命令から終了プログラム命令までのプログラム命令からなるプログラム命令群を基本ブロックとする。【００５２】
対象プログラム２１００を構成する全てのプログラム命令は、基本ブロック生成ステップにより、いずれかの一つの基本ブロックに含まれるように分割される（図７参照）。なお、これらの対象プログラムやブロックは、必要に応じて他の機能部から参照等することが可能であるものとする。
＜写像情報生成部１３００の処理＞
プログラム分割部１２００は、生成したブロックを、写像情報生成部１３００に渡し、写像情報生成部１３００は、各ブロックの入口と出口に設定する写像情報を生成する。これらの処理は、写像情報生成部１３００を構成するコントロールフロー生成部１３１０、属性情報割当表生成部１３２０および写像対応表生成部１３３０によって行われる。【００５３】
ここで、各ブロックの入口と出口に設定する写像情報について説明する。
これら入口の写像情報（以下、「入口写像情報」という。）と出口の写像情報（以下、「出口写像情報」という。）は、ブロック変換部１４００や秘密ブロック変換部１５００で、ブロックを変換する際に使用される情報である。
写像情報は、ｐｍ＿Ｘ（Ｘ＝０、１）が取りうる値を要素とする集合を集合ＰＭ＿Ｘとし、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、ｐｍ＿０＿ａｆｔｅｒ∈ＰＭ＿０、ｐｍ＿１＿ａｆｔｅｒ∈ＰＭ＿１を満たす（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に対応させる写像であって、写像による像（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が１点（例えば、（０、１））となる写像を示す。【００５４】
例えば、写像情報「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」は、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす全ての（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、（０、１）に対応させる写像を示す。これは、より具体的には、追加変数ｐｍ＿０、ｐｍ＿１の値を（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値である（０、１）にする変換を示す写像である。【００５５】
＜コントロールフロー生成部１３１０の処理＞
ブロック分割部１２００は、対象プログラム２１００を分割して生成した基本ブロックを、写像情報生成部１３００を介してコントロールフロー生成部１３１０に渡し、コントロールフロー生成部１３１０は、コントロールフローを生成する（ステップＳ１４０）。
図８は、対象プログラム２１００のコントロールフローを示す図である。【００５６】
コントロールフローはノードとエッジとからなるグラフであり、本図において、ノード１〜ノード５は、コントロールフローを構成するノードを示し、エッジ１〜エッジ６はコントロールフローを構成するエッジを示す。
コントロールフロー生成部１３１０は、対象プログラム２１００の基本ブロック（図７参照）から、図８に示すコントロールフローを以下の方法で生成する。【００５７】
まず、コントロールフロー生成部１３１０は、対象プログラム２１００に含まれるブロックＢ１〜ブロックＢ５に対応するノード１〜ノード５を生成する。
次に、第一のブロックから第二のブロックに分岐がある場合、第一のブロックが対応するノードから第二のブロックが対応するノードへエッジを設ける。
例えば、ブロックＢ１では、プログラム命令「ｉｆ（ｐｍ＿ａ＞ｐｍ＿ｂ）ｇｏｔｏ  ｌａｂｅｌ  Ｃ；」における条件式「ｐｍ＿ａ＞ｐｍ＿ｂ」が偽の場合は（図７参照）、ブロックＢ２に分岐し、真の場合は、「ｌａｂｅｌ  Ｃ：」に対応するブロックＢ３に分岐する。【００５８】
よって、ブロックＢ１に対応するノード１から、ブロックＢ２に対応するノード２へのエッジ１および、ブロックＢ３に対応するノード３へのエッジ２を設ける。
以下、同様にエッジ３〜エッジ６を設ける。
なお、本明細書では、分岐先が複数存在するものに限らず、ブロック間の移動が起こることを全て「分岐」と呼ぶものとする。【００５９】
コントロールフローの生成については、「コンパイラの構成と最適化」（中田育夫、朝倉書店（１９９９年））のＰ２６８〜２７０に詳しい記載がある。
＜属性情報割当表生成部１３２０の処理＞
コントロールフローを生成したコントロールフロー生成部１３１０は、生成したコントロールフローを属性情報割当表生成部１３２０に渡し、属性情報割当表生成部１３２０は、渡されたコントロールフローを基に属性情報割当表１８００を生成する（ステップＳ１５０）。【００６０】
属性情報割当表生成部１３２０は、コントロールフロー生成部１３１０が生成したブロックの入口と出口に属性を設定する。後で説明する写像対応表生成部１３３０が、この属性に対して写像情報を決定し、各ブロックの入口と出口に写像情報が設定されることになる。入口に設定される属性を入口属性、出口に設定される属性を出口属性というものとする。【００６１】
このブロックの入口と出口に属性を設定する際、第一のブロックから第二のブロックに分岐がある場合には、第一のブロックの出口属性と第二のブロックの入口属性とは同じ写像情報とする。
例えば、図８に示すコントロールフローにおいて、ブロックＢ１に対応するノード１からブロックＢ２に対応するノード２にエッジ１に示される分岐があるので、ブロックＢ１の出口属性と、ブロックＢ２の入口属性には同じ属性を設定する。【００６２】
すなわち、エッジの両端の入口と出口に同じ属性が割当てられることになるように、エッジに対して属性を割当てる。
また、繋がっているエッジのまとまりごとに１つの属性を割当てる。
例えば、ノード３の出口で繋がっているエッジ４とエッジ５、および、ノード３の入口でエッジ４と繋がっているエッジ２、ノード１の出口でエッジ２と繋がっているエッジ１とは、同じ属性を割当てる。【００６３】
これらのエッジに同じ属性を割当てることで、エッジ１とエッジ２とエッジ４とエッジ５の両端の入口と出口とは、同じ属性となる。具体的には、ノード１の出口、ノード２に入口、ノード３の入口と出口、ノード４の入口は同じ属性となる。
図９は、属性情報割当表生成部１３２０が生成する属性情報割当表１８００の生成過程と、構成及び内容の例を示す図である。【００６４】
属性情報割当表１８００は、ブロック１８１０、エッジ１８２０および属性１８３０とで構成される。
ブロック１８１０は、ブロックＢ１〜ブロックＢ５のそれぞれの入口と出口を示し、エッジ１８２０は、ブロックの入口と出口がそれぞれ接続しているエッジの番号を示す。例えば、「１」はエッジ１を表す。また、属性１８３０は、ブロックの入口と出口それぞれに設定された属性を示す。【００６５】
この属性の決定方法を、図１０を用いて説明する。
図１０は、属性情報割当表生成処理を表すフローチャートである。
まず、属性情報割当表生成部１３２０は、コントロールフロー生成部１３１０が生成したブロック数の２倍の欄を持つテーブルを作成する（ステップＳ３１０）。
ここでは、コントロールフロー生成部１３１０が生成したブロック数が５であることより、１０個の欄からなるテーブルを作成する（図９参照）。【００６６】
次に、属性情報割当表生成部１３２０は、属性１８３０に昇順に異なる数値を初期値として設定する。具体的には属性１８３０のブロック１８１０「ブロックＢ１入口」の欄から「ブロックＢ５出口」の欄に向かって、初期値「１」、「２」、・・・「１０」を設定する（ステップＳ３２０：図９の属性１８３０参照）。
初期値を設定した属性情報割当表生成部１３２０は、Ｓ３４０からＳ３６０を繰り返し実行する回数をカウントするためのカウンタｎに１を設定する（ステップＳ３３０）。【００６７】
次に、出口のエッジ１８２０が「ｎ」のブロック、すなわち、エッジの始点となるブロックの出口の属性１８３０の値Ａと、入口のエッジ１８２０が「ｎ」のブロック、すなわち、エッジの終点となるブロックの入口の属性１８３０の値Ｂとを比較し、大きい方の値をＸ、小さい方の値をＹとし、写像情報割当表において値がＸである欄の値をＹに置換える（ステップＳ３４０）。【００６８】
例えば、「ｎ＝＝１」の場合、すなわち、出口のエッジ１８２０が「１」のブロックはブロックＢ１、入口のエッジ１８２０が「１」のブロックはブロックＢ２である。これらの「ブロック１出口」と「ブロック２入口」の属性１８３０は、それぞれ「２」と「３」であり、小さい値である「２」で「３」を置き換える。すなわち、ブロックＢ２の入口の属性１８３０を「３」から「２」（属性１８０１参照）とする。【００６９】
次に、ｎの値をインクリメントする（ステップＳ３５０）。
ｎの値がエッジの総数、本例では「６」より大きいかを判定し、大きい場合（ステップＳ３６０：ＹＥＳ）は全エッジに対する処理が終了しているため処理を終了し、小さい場合（ステップＳ３６０：ＮＯ）は次のエッジについて処理を続ける（ステップＳ３４０）。【００７０】
続いて、「ｎ＝＝２」の場合、エッジ２の始点となるブロックＢ１の出口の属性の値「２」、終点となるブロックＢ３の入口の属性の値「５」を比較し、大きい方の値Ｘを「５」とし、小さい方の値Ｙを「２」とする。値「５」がある欄の値を「２」に置換え（属性１８０２参照）、１０個の欄の値を「１、２、２、４、２、６、７、８、９、１０」に更新する。【００７１】
同様に、「ｎ＝＝３」の場合、エッジ３の始点となるブロック２の出口属性の値が「４」、終点となるブロックＢ５の入口属性の値が「９」であるので、値「９」がある欄の値を「４」に置換え（属性１８０３参照）、１０個の欄の値を「１、２、２、４、２、６、７、８、４、１０」に更新する。
同様に、「ｎ＝＝６」まで行い、ブロック４の出口属性の値「８」を、ブロックＢ５の入口属性の値「４」で置換え（属性１８０４参照）、１０個の欄の値を「１、２、２、４、２、２、２、４、４、１０」（属性１８３１参照）に更新する。【００７２】
図１１は、各ブロックの入口と出口に設定された属性を示した、コントロールフローである。
＜写像対応表生成部１３３０の処理＞
属性情報割当表１８００を生成した属性情報割当表生成部１３２０は、生成した属性情報割当表を写像対応表生成部１３３０に渡し、写像対応表生成部１３３０は、渡された属性情報割当表の各属性に写像情報対応させる写像対応表１９００を生成する（ステップＳ１６０）。【００７３】
写像対応表１９００は、属性情報割当表１８００中の属性に対応する写像情報を示している。従って、この写像対応表１９００を参照することにより、各ブロックに割り当てられた写像情報が得られることになる。
また、属性情報割当表１８００と写像対応表１９００は、図示しないメモリ上に生成されるものとする。【００７４】
写像対応表生成部１３３０は、写像情報割当表１８００を構成する属性１８３１の属性数の写像情報を生成する。
図１２は、写像対応表１９００の構成および内容の例を示す図である。
属性１９５０は、写像情報割当表１８００の最終的な属性１８３１における属性の一覧である。また、写像対応表１９００は、ＩＤ１９１０と写像情報１９２０とで構成される。ＩＤ１９１０は、写像情報１９２０の識別子であり、属性１９５０と対応しているものとする（図１２：点線矢印参照）。【００７５】
本実施例においては、写像情報割当表１８００の最終的な属性１８３１に属性が４種類、すなわち、「１」、「２」、「４」、「１０」であるので（図９参照）、４種類の写像情報を作成する。
以下、写像対応表生成部１３３０が写像情報１９２０を生成する手順を具体例を交えて説明する。【００７６】
まず、コントロールフローの始点となるブロックの入口属性に対応する写像情報１９２０を、変数追加部１１００が追加した追加変数の初期値に基づいて設定する。
本実施形態では、始点となるブロックＢ１の入力属性は「１」であり（図１１参照）、追加変数「ｐｍ＿０」、「ｐｍ＿１」の初期値はそれぞれ「０」、「１」である。
従って、属性１９５０「１」に対応するＩＤ１９１０「Ｆ１」の写像情報１９２０（以下、「写像情報Ｆ１」等というものとする。）として、「ｐｍ＿０」、「ｐｍ＿１」の初期値を「ｐｍ＿０＿ａｆｔｅｒ」、「ｐｍ＿１＿ａｆｔｅｒ」とする写像情報を生成する。【００７７】
すなわち、「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」を写像情報Ｆ１とする（図１２：ＩＤ１９１０「Ｆ１」参照）。
続いて、始点の入力属性以外の属性、「２」と「４」と「１０」に対する写像を、ランダムに生成する。
本実施形態では、属性「２」「４」「１０」に対応する写像情報として、ｐｍ＿Ｘ∈ＰＭ＿Ｘ（Ｘ＝０、１）を満たすランダムな値ｐｍ＿Ｘをｐｍ＿Ｘ＿ａｆｔｅｒの値とするような写像情報を生成する。【００７８】
本実施形態では、属性「２」の写像情報Ｆ２を「ｐｍ＿０＿ａｆｔｅｒ＝３０；ｐｍ＿１＿ａｆｔｅｒ＝６；」と、属性「４」の写像情報Ｆ４を「ｐｍ＿０＿ａｆｔｅｒ＝１２；ｐｍ＿１＿ａｆｔｅｒ＝７；」と、属性「１０」の写像情報Ｆ１０を「ｐｍ＿０＿ａｆｔｅｒ＝１３；ｐｍ＿１＿ａｆｔｅｒ＝３１；」とする（図１２：写像対応表１９００参照）。【００７９】
＜ブロック変換部１４００の処理＞
写像対応表１９００を生成した写像対応表生成部１３３０は、生成した写像対応表をブロック変換部１４００に渡し、ブロック変換部１４００は、渡された写像対応表に基づいて各ブロックにプログラム命令を追加し、変換後ブロックを生成する（ステップＳ１７０）。【００８０】
全てのブロック、本実施形態ではブロックＢ１〜ブロックＢ５に、それぞれプログラム命令が追加されるまで（ステップＳ１８０）、ステップＳ１７０の処理を行う。
図１３は、ブロックＢ１〜ブロックＢ５を、ブロック変換部１４００が変換して生成した変換後ブロックを示す図である。プログラム命令群１４０１〜プログラム命令群１４０５は、それぞれのブロックに追加されたプログラム命令を表す。【００８１】
ブロック変換部１４００は、もともとのブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する。
ここで、追加する機能は、追加変数の値が入口写像情報に示される値であった場合に、追加変数の値を出口写像情報に示される値に変換する機能である。具体的には、このような機能を実行するプログラム命令を追加する。【００８２】
以下、追加する機能の具体例を説明した後、追加する機能を実現するためのプログラム命令の生成について説明する。
＜追加する機能＞
まず、ブロックＢ１に追加する機能を説明する。
ブロックＢ１に追加する機能は、写像情報Ｆ１を写像情報Ｆ２に変換するような機能であり（図１１参照）、この機能を実現するプログラム命令群を「Ｇ＿１＿２」というものとする。【００８３】
ブロックＢ１の入口写像情報Ｆ１は「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」であり、出口写像情報Ｆ２は、「ｐｍ＿０＿ａｆｔｅｒ＝３０；ｐｍ＿１＿ａｆｔｅｒ＝６；」である（図１２：写像対応表１９００参照）。
従って、ブロックＢ１に追加する機能は、（ｐｍ＿０、ｐｍ＿１）の値が入口写像情報Ｆ１における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値（０、１）である場合に、（ｐｍ＿０、ｐｍ＿１）の値を出口写像情報Ｆ２の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が示す（ｐｍ＿０、ｐｍ＿１）の値（３０、６）と等しくなるよう、（ｐｍ＿０、ｐｍ＿１）の値を変換する機能である。【００８４】
具体的には、「ｐｍ＿０＝０」、「ｐｍ＿１＝１」であった場合に、「ｐｍ＿０＝３０」、「ｐｍ＿１＝６」となるような命令群であり、プログラム命令群Ｇ＿１＿２は「ｐｍ＿０＝ｐｍ＿０＊５＋ｐｍ＿１＊２０＋１０；  ｐｍ＿１＝ｐｍ＿１  ＊１３−７；」となる（図１３：プログラム命令群１４０１参照）。
なお、このような命令をどのように生成するかについては後述する。【００８５】
プログラム命令群Ｇ＿１＿２、すなわち、プログラム命令群１４０１を追加することにより、（ｐｍ＿０、ｐｍ＿１）の値が入口写像情報Ｆ１における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値（０、１）である場合に、プログラム命令群１４０１「ｐｍ＿０＝０＊５＋１＊２０＋１０；ｐｍ＿１＝１＊１３−７；」が実行されることとなり、（ｐｍ０、ｐｍ１）＝（３０、６）となる。これは、出口写像情報Ｆ２の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が示す（ｐｍ＿０、ｐｍ＿１）の値と等しい値である。【００８６】
更に、他のブロック、ブロックＢ２〜ブロックＢ５に対しても同様の機能を持つプログラム命令群を追加する。
すなわち、プログラム命令群１４０２〜プログラム命令群１４０５も同様に、各ブロックの入口写像情報における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を代入すると、各ブロックの出口写像情報における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）となるような処理を行うためのプログラム命令群である（図１３参照）。【００８７】
＜追加する処理の生成＞
以下、上述したプログラム命令群Ｇ＿１＿２等をどのようにして生成するのかについての詳細を述べる。
入口写像情報としてＦ＿ＩＮを、出口写像情報としてＦ＿ＯＵＴを持つブロックに対する命令群Ｇ＿ＩＮ＿ＯＵＴを生成する場合の説明を行う。【００８８】
例えば、Ｆ＿ＩＮとＦ＿ＯＵＴは、ブロックＢ１へ追加する命令群を生成する場合にはＦ１とＦ２であり、ブロックＢ２へ追加する命令群を生成する場合にはＦ＿２とＦ＿４である。
まず、ランダムに生成した定数をＲ１、Ｒ２、Ｒ３とし、式１、式２を、式１「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊Ｒ１−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ２」、式２「ｐｍ＿１＿ａｆｔｅｒ−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ３」
とする。【００８９】
次に、（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に出口写像情報Ｆ＿ＯＵＴの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｏｆｏｒｅ）に入口写像情報Ｆ＿ＩＮの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値をそれぞれ代入し、式１、式２の値を計算し、それぞれの値をＶ１、Ｖ２とする。【００９０】
計算したＶ１、Ｖ２を用いて、追加プログラム命令群Ｇ＿ＩＮ＿ＯＵＴを「ｐｍ＿０＝ｐｍ＿０＊Ｒ１＋ｐｍ＿１＊Ｒ２＋Ｖ１；ｐｍ＿１＝ｐｍ＿１＊Ｒ３＋Ｖ２」とする。
以下、具体的な一例として、Ｒ１、Ｒ２、Ｒ３をそれぞれ「５」「２０」「１３」としてブロックＢ１に追加する追加プログラム命令群Ｇ＿１＿２を生成する処理を説明する。
上述したＲ１、Ｒ２、Ｒ３の値を代入すると、式１、式２は、「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊５−ｐｍ＿１＿ｂｅｆｏｒｅ＊２０」「ｐｍ＿１＿ａｆｔｅｒ−ｐｍ＿１＿ｂｅｆｏｒｅ＊１３」となる。【００９１】
上式の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に出口写像情報Ｆ２の値（３０、６）を代入し、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）に入口写像情報Ｆ１の値（０、１）を代入すると、それぞれ「３０−０＊５−１＊２０」「６−１＊１３」となる。すなわち、Ｖ１、Ｖ２はそれぞれ「１０」「−７」となる。
よって、プログラム命令群Ｇ＿１＿２は「ｐｍ０＝ｐｍ０＊５＋ｐｍ１＊２０＋１０：ｐｍ＿１＝ｐｍ＿１＊１３−７；」となる。このようにして生成した追加プログラム命令群Ｇ＿１＿２をブロックＢ１の先頭に追加し、変換後ブロックとする（図１３：プログラム命令群１４０１参照）。【００９２】
＜秘密ブロック変換部１５００の処理＞
変換後ブロックを生成したブロック変換部１４００は、生成した変換後ブロックを秘密ブロック変換部１５００に渡し、秘密ブロック変換部１５００は、渡された変換後ブロックから秘密情報を含む秘密ブロックを特定し（ステップＳ１９０）、秘密情報を追加変数を用いて算出する式に置き換えて、難読化プログラムを生成する（ステップＳ２００）。【００９３】
ここで、秘密ブロックの特定の方法は、対象プログラム２０００から秘密情報を検出し、その秘密情報が含まれるブロックを秘密ブロックとして特定する。
秘密情報を検出する方法としては、予め、秘密情報を特定のコードで囲んでおいたり、難読化開始前にユーザが指定する等して、秘密ブロック変換部１５００が認識できるようにしておく。また、秘密ブロックの中に秘密情報は複数あってもよく、また、対象プログラム中に秘密ブロックが複数あってもよい。【００９４】
次に、秘密ブロック変換部１５００は、プログラムに含まれる秘密情報を、変数追加部１１００で追加した追加変数を用いて算出する処理に変更する。
このようにして生成した変換後の秘密ブロックを含む難読化後プログラム３０００を、図１４に示す。
以下、秘密情報を追加変数を用いて算出するプログラム命令の求め方を説明する。【００９５】
まず、ランダムに生成した定数をＲ４、Ｒ５とし、以下の式３を生成する。
式３「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊Ｒ４−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ５」。
次に、「ｐｍ＿０＿ａｆｔｅｒ」に秘密情報の値を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）に秘密ブロックの出口写像情報Ｆ＿ＯＵＴの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を代入して式３の値を計算し、計算した値をＶ３とする。【００９６】
ここでは、秘密ブロックであるブロックＢ５（図１３参照）に含まれる秘密情報の値「１２３」の変換を例にとり説明する。
秘密情報「１２３」を含むブロックはブロックＢ５であり、ブロックＢ５の出口写像情報Ｆ１０の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）は（１３、３１）である。
Ｒ４、Ｒ５をそれぞれ「３」、「４」とし、これらを式３に代入し、「１２３−１３＊３−３１＊４」よりＶ３の値「−４０」を求める。【００９７】
次に、秘密情報の値を「（ｐｍ＿０＊Ｒ３＋ｐｍ＿１＊Ｒ４＋Ｖ３）」に置き換える。すなわち、プログラム命令「ｂ＝ｂ＊１２３；」を「ｂ＝ｂ＊（３＊ｐｍ＿０＋４＊ｐｍ＿１−４０）；」に置き換える（図１４：プログラム命令１５０１参照）。
ここで、最終的に得られる上式は、ブロックＢ５における入力写像情報（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）の値にランダムな数Ｒ３、Ｒ４をかけて加算した演算結果と秘密情報「１２３」との差分Ｖ３を算出し、加算する式となっている。【００９８】
これにより上式の計算結果は、入口属性が属性情報割当表１８００の属性１８３１に示される値「４」（図９参照）である場合には、常に秘密情報「１２３」が得られる。
難読化後プログラム３０００は、秘密ブロック変換部１５００により生成された秘密情報変換後のブロックＢ５と、ブロック変換部１４００により生成された変換後ブロックＢ１〜ブロックＢ４とを備えるプログラムである。【００９９】
難読化プログラム３０００は、出力部により外部メモリ１３に出力される（ステップＳ２１０）。
＜実施形態１の効果＞
実施形態１では、秘密情報を、複数のプログラム命令を実行することによって算出されるように変換する難読化の一例を示した。この難読化方法は以下の３点を特徴とする。【０１００】
（イ）コントロールフローの始点となるブロック、例えばブロックＢ１、の入口属性Ｆ＿ＩＮを、追加変数の初期値とする（写像対応表生成部１３３０の処理参照）。
（ロ）各ブロックに、追加変数がそのブロックの入口写像情報Ｆ＿ＩＮで示す値であった場合に、そのブロックの出口写像情報Ｆ＿ＯＵＴに示す値に変換する機能が追加される（ブロック変換部１４００の処理参照）。【０１０１】
（ハ）複数の分岐元を持つノードの全ての分岐元のノードに対応するブロックの出口写像情報は、分岐先のノードに対応するブロックの入口写像情報と等しい（属性情報割当表１８００参照）。例えば、ブロックＢ５のように２つの分岐元ブロックＢ２とブロックＢ４とを持つ場合、ブロックＢ２とブロックＢ４のブロックＢ５に対する出口写像情報は、ブロックＢ５の入口写像情報と等しい（図１１参照）。【０１０２】
以上、３点の特徴により、正常系の実行時において、難読化後プログラムがどのような実行ルートで実行されたとしても、追加変数の値はその秘密ブロックに対して（ロ）で設定した入口写像情報に示される値となる。
よって、秘密情報を含むブロックＢ５の入口写像情報に基づき算出される秘密情報の値は、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されたとしても、正しい値「１２３」となる。【０１０３】
本実施形態の難読化プログラムでは、追加変数の値を算出するプログラム命令が全てのブロックに追加されている。また、秘密情報は、追加変数を用いて算出される。よって、不正解析者が、追加されたプログラム命令を見つけ出して秘密情報の値を解析しようとした場合、追加されたプログラム命令がプログラムの様々な位置にあるので、追加されたプログラム命令すべてを見つけ出すことが困難になる。従って、秘密情報に至るまでに長時間を要し、結果として秘密情報が守られる事となる。
＜実施形態２＞
＜概要＞
実施形態１が、新たな変数を追加し、この追加変数の値を算出するプログラム命令を全てのブロックに追加し、更に、秘密情報をかかる追加変数から算出する式に置き換えて難読化プログラムを生成するものであったのに対し、本実施形態では、対象プログラムに既に存在する変数を利用し、その変数の役割をプログラムの途中で置換えて難読化プログラムを生成するものである。【０１０４】
ここでは、実施形態１との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表４９００を図１５に示す。
写像対応表４９００は、ＩＤ１９１０と写像情報４９２０とで構成され、ＩＤ１９１０は実施形態１と同様に、写像情報４９２０の識別子である。また、変数の置換え関係４９３０は、写像対応表４９００を構成しないが、説明の便宜上、変数の置換え関係を矢印を用いて表したものである。【０１０５】
すなわち、実施形態１の写像対応表１９００（図１２参照）では、属性に応じて、変数の値がある値に決まったが、本実施形態では、属性に応じて、変数の値がどの変数の値となっているかが決まることになる。
＜構成＞
図１６は、実施形態２にかかるプログラム難読化装置４０００の構成例を示すブロック図である。【０１０６】
実施形態１のプログラム難読化装置１０００の構成（図２参照）と異なる点は、４点ある。
１点目は、変数追加部１１００が無い点であり、２点目は、写像情報生成部４４００の写像対応表生成部４３３０が生成する写像の内容が異なる点である。３点目は、写像の内容が異なることによるブロック変換部４４００で追加するプログラム命令群の生成方法が異なる点である。また、４点目は、追加変数が追加されていないため、秘密ブロック変換部４５００での秘密情報の算出方法が異なる点である。【０１０７】
＜動作＞
以下、写像情報生成部４４００の写像対応表生成部４３３０、ブロック変換部４４００、秘密ブロック変換部４５００の処理について説明する。他の動作は、実施形態１と同様である（図５等参照）。
＜写像情報生成部４４００の写像対応表生成部４３３０の処理＞
写像情報生成部４４００は、プログラム分割部１２００で生成した各ブロックの入口と出口に設定する写像情報を生成する。【０１０８】
本実施形態で設定する写像情報について、簡単に説明する。
写像情報は、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）が取りうる値を要素とする集合を集合ＰＭ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）とし、ｐｍ＿ａ＿ｂｅｆｏｒｅ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）をｐｍ＿ａ＿ａｆｔｅｒ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ａｆｔｅｒ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ａｆｔｅｒ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、  ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像であって、変数の役割を置換える写像を示す。【０１０９】
具体的には、例えば写像情報「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の値がそれぞれ（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）であった場合に、それぞれの値を変数（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に代入する写像を示している。すなわち、上述の写像情報は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割をそれぞれ（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に置換える置換えを示した写像を示している。【０１１０】
＜写像対応表生成部４３３０の処理＞
写像対応表生成部４３３０は、実施形態１と同様、属性情報割当表１８００の属性に対応する写像情報を示す写像対応表４９００を生成する。
なお、本実施形態において、属性情報割当表は実施形態１の属性情報割当表１８００と同じである（図９参照）。【０１１１】
写像対応表生成部４３３０は、属性情報割当表１８００を構成する属性の種類数、すなわち、４種類の写像情報を生成する。
各写像情報の作成は、例えば以下のようにして行う。
ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅからランダムに選んだ１つをｐｍ＿ａ＿ａｆｔｅｒに対応させ、残りの二つからランダムに選んだ１つをｐｍ＿ｂ＿ａｆｔｅｒに対応させ、さらに残りの１つをｐｍ＿ｃ＿ａｆｔｅｒに対応させる。【０１１２】
例えば、「ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ、」を順に選んだ場合、写像情報は、「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」となる。
本実施形態では、図１１のコントロールフローの始点となるブロックＢ１の入口写像情報の属性「１」に対応する写像情報Ｆ１を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」とする。【０１１３】
また、順次、他の属性「２」「４」「１０」に対応する写像情報を決め、写像対応表４９００を完成させる。
＜ブロック変換部４４００の処理＞
ブロック変換部４４００は、もともとのブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する手段である。追加する機能は、入口写像情報に示される変数の置換えが行われている場合に、出口写像情報を示す変数の置換えを行う機能である。また、この置換えは、もとからあるプログラム命令で使用されている変数を用いて行う。【０１１４】
以下、追加する機能および変数の置換えを説明した後、追加する機能を実現するための処理の生成について説明する。
＜追加する機能＞
ブロックに追加する機能を、具体例を用いて説明する。
図１７は、図７のブロックＢ２をブロック変換部４４００によって変換して生成した変換後ブロックＢ２を示す図である。【０１１５】
白抜き矢印の左側に変換前のブロックＢ２（以下、「変換前ブロックＢ２」という。）を、右側に変換後のブロックＢ２（以下、「変換後ブロックＢ２」という。）を示している。
変換後ブロックＢ２は、変換前ブロックＢ２に、変数の役割を置換えるプログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ：ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｔｍｐ；」（図１７：プログラム命令群４４０１参照）を追加し、さらに、変換前ブロックＢ２に含まれる変数を出口写像情報Ｆ４に基づいて置き換えて（プログラム命令群４４０２参照）生成したブロックである。【０１１６】
プログラム命令群Ｇ＿２＿４は、変数の役割を置換えるためのプログラム命令群であり、ブロックＢ２が正常系で実行される際に、このブロックＢ２が実行される前までに入口写像情報に基づき変数の役割が置換えられていた場合に、出口写像情報に基づく変数の置換えを行うプログラム命令群である。
以下、プログラム命令群４４０２で示されるプログラム命令群Ｇ＿２＿４が、上記の特徴を持つプログラム命令群であることを説明する。【０１１７】
まず、ブロックＢ２の入口写像情報は図１１に示すようにＦ２であり、出口写像情報はＦ４である。
図１８は、ブロックＢ２の入口と出口での変換を示した図である。なお、Ｆ２＿ＩＮＶは、Ｆ２の逆写像をあらわすものとする（変換４４２０）。
入口写像情報Ｆ２は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に置換える置換え（変換４４１０）であって、出口写像情報Ｆ４は変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ｂ、ｐｍ＿ａ、ｐｍ＿ｃ）に置換える置換え（変換４４３０）である（図１５：写像対応表４９００参照）。【０１１８】
また、プログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ：ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｐｍ＿ａ；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ｂ、ｐｍ＿ｃ、ｐｍ＿ａ）に置換える処理である。
この時、入口写像情報Ｆ２による置換えと、プログラム命令群Ｇ＿２＿４による置換えの両方を行った際の置換えを図１９の下段に示す。【０１１９】
図１９に示すように、入口写像情報Ｆ２の置換え（変換４４１０）を行った後、さらにプログラム命令群Ｇ＿２＿４による置換え（変換４４９０）を行った場合、もともとの（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）を（ｐｍ＿ｂ、ｐｍ＿ａ、ｐｍ＿ｃ）に置換えた置換えと等しくなる。これは出口写像情報Ｆ４の示す置換えと等しい。
なお、プログラム命令群Ｇ＿２＿４の生成方法については、後述する。【０１２０】
＜変数の置換え＞
さらに、ブロックＢ２では、ブロックに含まれる変数を出口写像情報Ｆ４に基づき書き換える必要がある。
具体的には、ブロックＢ２における「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」におけるｐｍ＿ｂを出口写像情報Ｆ＿４に基づいてｐｍ＿ａに置換えて「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」とする（図１７：プログラム命令４４０２）。【０１２１】
＜追加する処理の生成＞
以下、上述したプログラム命令群Ｇ＿２＿４等をどのようにして生成するのかについて詳細を述べる。
変換を行うブロックの入力写像情報をＦ＿ＩＮ、出口写像情報をＦ＿ＯＵＴとし、入力写像情報Ｆ＿ＩＮによる置換えの逆変換をＦ＿ＩＮ＿ＩＮＶとする。【０１２２】
例えば、変換を行うブロックがブロックＢ２のとき、Ｆ＿ＩＮは、Ｆ２であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に対応させる写像である（図１８：変換４４１０参照）。
この時、Ｆ２＿ＩＮＶは、Ｆ＿２のｐｍ＿Ｘ＿ａｆｔｅｒとｐｍ＿Ｘ＿ｂｅｆｏｒｅとを置換えた写像であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に対応させる写像となる（図１８：変換４４２０参照）。【０１２３】
次に、Ｆ＿ＩＮ＿ＩＮＶとＦ＿ＯＵＴの合成による置換えを求める。
例えば、対象ブロックがブロックＢ２である場合、Ｆ＿ＯＵＴはＦ４であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像となる（図１８：変換４４３０参照）。【０１２４】
この時、Ｆ＿Ｉ＿ＩＮＶとＦ＿ＯＵＴの合成による置換えは、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ａ＿ａｆｔｅｒ）に対応させる写像となる（図１９：変換４４９０）。
次に、上記の置換えを行う追加プログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ；ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｔｍｐ；」を生成し、ブロックＢ２に追加する。【０１２５】
その後、出口写像情報Ｆ＿ＯＵＴの示す置換えに基づき、ブロックＢ２に含まれる変数を置換える。
具体的には、ブロックＢ２に対応する出口写像情報Ｆ４が「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」を含むことから、変数ｐｍ＿ｂはｐｍ＿ａに置換えられたことが分かるので、ブロックＢ２のｐｍ＿ｂをｐｍ＿ａに置き換える。すなわち、式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」に置換える。【０１２６】
このようにして生成したブロックが変換後ブロックＢ２となる。他のブロックＢ１、ブロックＢ３〜ブロックＢ５についても同様に変換を行う。
このような変換を行うことにより、各ブロックは常に、一つ前のブロックの出口写像情報に対応する変換を打ち消した後、自身の出口写像情報に対応する変換を行う。
これにより、正常系の実行時には、各ブロックでどのように分岐やループが発生したとしても、各ブロックにおける変数の置換えの状態は、図１５に示される写像情報４９２０が示すものと等しくなる。【０１２７】
また、出口写像情報に基づいて変換前のブロックに含まれる変数を置換えるので、各ブロックの演算結果が変換前のブロックと等しくなることが保証できる。
＜秘密ブロック変換部４５００の処理＞
実施形態１では、秘密情報は追加変数を用いた式で求めたが、本実施形態では追加変数は追加されない。従って、本実施形態では、秘密情報の変更しないものとするが、変換した変数を用いたり、他の変数を用いて難読化することとしてももちろんよい。【０１２８】
＜実施形態２の効果＞
実施形態２では、変数の役割をプログラムの途中で置換える難読化の一例を示した。この難読化方法は以下の４点を特徴とする。
（イ）コントロールフローの始点となるノード２に対応するブロックＢ２の入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てている（写像対応表生成部４３３０の処理参照）。【０１２９】
（ロ）各ブロックに、変数の置換えが入口写像情報Ｆ＿ＩＮで示す置換えであった場合に、出口写像情報Ｆ＿ＯＵＴに示す変数の置換えを行う機能が追加される（ブロック変換部４４００の処理参照）。
（ハ）ノード５のような複数の分岐元（ノード２、ノード４）を持つノードに対応する全ての分岐元のブロックの出口写像情報は、分岐先のノード（ノード５）に対応するブロックの入口写像情報と等しい（属性情報割当表１８００参照）。【０１３０】
（ニ）各ブロックの変数は出口写像情報に基づき置換えられている。
以上、４点の特徴により、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されても、各ブロックに実行制御が遷移した際、変数は、そのブロックの入口写像情報に示す置換えが成された変数となる。
このような難読化により、プログラムの様々な位置で変数の役割が置換わり、プログラムの解析を困難にすることができる。また、ブロック毎に、変数の役割が替わることにより、あるブロックでの変数が、他のブロックでどの変数になっているかが解り難くなるので、解析を困難にすることができる。
＜実施形態３＞
＜概要＞
実施形態２が、対象プログラムに既に存在する変数を利用し、その変数の役割をプログラムの途中で置換えて難読化プログラムを生成するものであったのに対し、本実施形態では、変数の値に所定の演算を施した値を、その変数に保持させることで難読化プログラムを生成するものである。例えば、変数ｐｍ＿ａに１４を足した値を、変数ｐｍ＿ａに保持させるなどである。【０１３１】
ここでは、実施形態２との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表５９００を図２０に示す。
写像対応表５９００は、ＩＤ１９１０と写像情報５９２０とで構成され、ＩＤ１９１０は実施形態２と同様に、写像情報５９２０の識別子である。【０１３２】
すなわち、実施形態２の写像対応表４９００（図１５参照）では、属性に応じて、変数の値がどの変数の値となっているかが決まったが、本実施形態では、属性に応じて、変数の値が、どの様な演算が施された値であるかが決まることになる。
＜構成＞
図２１は、実施形態３にかかるプログラム難読化装置５０００の構成例を示すブロック図である。【０１３３】
実施形態２のプログラム難読化装置４０００の構成（図１６参照）と異なる点は、以下の２点である。
１点目は、写像情報生成部５４００の写像対応表生成部５３３０が生成する写像の内容が異なる点である。２点目は、写像の内容が異なることによるブロック変換部５４００で追加するプログラム命令群の生成方法が異なる点である。【０１３４】
＜動作＞
以下、写像情報生成部５４００の写像対応表生成部５３３０、ブロック変換部５４００の各処理について説明する。他の動作は、実施形態１および実施形態２と同様である（図５、図１６等参照）。
＜写像情報生成部５４００の写像対応表生成部５３３０の処理＞
まず、本実施形態で設定する写像情報について説明する。【０１３５】
実施形態３の写像情報は、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）が取りうる値を要素とする集合を集合ＰＭ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）とし、ｐｍ＿ａ＿ｂｅｆｏｒｅ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂを満たす（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）をｐｍ＿ａ＿ａｆｔｅｒ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ａｆｔｅｒ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ａｆｔｅｒ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像であって、変数ｐｍ＿Ｘ＿ｂｅｆｏｒｅにある数を加減算したものをｐｍ＿Ｘ＿ａｆｔｅｒに対応させる写像を示す。【０１３６】
例えば、写像情報「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒ＋１４；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋１２；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ−６；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の値がそれぞれ（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）であった場合に、（ｐｍ＿ａ＿ｂｅｆｏｒｅ＋１４、ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋１２、ｐｍ＿ｂ＿ｂｅｆｏｒｅ−６）値をそれぞれ変数（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に代入する写像を示している。【０１３７】
すなわち、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割をそれぞれ（ｐｍ＿ａ＋１４、ｐｍ＿ｃ＋１２、ｐｍ＿ｂ−６）に置換える置換えを示す。
＜写像情報生成部５３００の写像対応表生成部５３３０の処理＞
写像対応表生成部５３３０は、実施形態２と同様、属性情報割当表１８００の属性に対応する写像情報を示す写像対応表５９００を生成する。【０１３８】
なお、本実施形態において、属性情報割当表は実施形態１の属性情報割当表１８００と同じである（図９参照）。
写像対応表生成部５３３０は、属性情報割当表１８００を構成する属性の種類数、すなわち、４種類の写像情報を生成する。
各写像情報の作成は例えば以下のようにして行う。【０１３９】
Ｒ１∈ＰＭ＿Ａ、Ｒ２∈ＰＭ＿Ｂ、Ｒ３∈ＲＭ＿Ｃを満たすＲ１、Ｒ２、Ｒ３をランダムに生成し、「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋Ｒ１；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋Ｒ２；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋Ｒ３；」を写像情報とする。
具体的には、図１１のコントロールフローの始点となるブロックの入口写像情報の属性「１」に対応する写像情報Ｆ１を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」とする。【０１４０】
次に、その他の識別子「２」「４」「１０」に対応する写像情報を決める。
＜ブロック変換部５４００の処理＞
ブロック変換部５４００は、変換前ブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する。ここで、追加する機能は、入口写像情報に示される変数の置換えが行われている場合に、出口写像情報を示す変数の置換えを行う機能である。【０１４１】
以下、追加する機能、追加する機能を実現するための処理の生成、および、変数の置換えについて説明する。
＜追加する機能＞
以下、ブロックに追加する機能を、具体例を用いて説明する。
図２２は、ブロックＢ２を、ブロック変換手段５４００によって変換して生成した変換後ブロックＢ２を示す図である。【０１４２】
白抜き矢印の左側に変換前ブロックＢ２を、右側に変換後ブロックＢ２を示している。
具体的には、変換前ブロックＢ２の先頭に、プログラム命令群Ｇ＿２＿ＩＮＶ（図２２：プログラム命令群５４０１参照）を追加し、その後にプログラム命令群Ｇ＿４（図２２：プログラム命令群５４０２参照）を追加する。
さらに、ブロックに含まれる変数をブロックの出口写像情報に基づいて変換する（図２２：プログラム命令５４０３参照）。【０１４３】
プログラム命令群Ｇ＿２＿ＩＮＶは、「ｐｍ＿ａ＝ｐｍ＿ａ−１４；  ｐｍ＿ｂ＝ｐｍ＿ｂ−１２；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋６；」であり、プログラム命令群Ｇ＿４は、「ｐｍ＿ａ＝ｐｍ＿ａ＋７；  ｐｍ＿ｂ＝ｐｍ＿ｂ＋５；  ｐｍ＿ｃ  ＝ｐｍ＿ｃ＋２１；」である。
以下、プログラム命令群Ｇ＿２＿ＩＮＶ、プログラム命令群Ｇ＿４の生成、および、ブロックに含まれる変数の置換えの詳細を説明する。【０１４４】
＜プログラム命令群Ｇ＿２＿ＩＮＶの生成＞
プログラム命令群Ｇ＿２＿ＩＮＶは、ブロックＢ２の入口写像情報Ｆ２の逆写像を行う追加プログラム命令群である。
プログラム命令群Ｇ＿２＿ＩＮＶの生成の仕方を説明する。
まず、写像情報Ｆ２より、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）を用いて求める式を生成する。【０１４５】
これは、「ｐｍ＿ａ＿ｂｅｆｏｒｅ＝ｐｍ＿ａ＿ａｆｔｅｒ−１４；  ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−１２；  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＝ｐｍ＿ｃ＿ａｆｔｅｒ＋６；」となる。
この式の、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換え、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘに置換えた「ｐｍ＿ａ＝ｐｍ＿ａ−１４；  ｐｍ＿ｂ＝ｐｍ＿ｂ−１２；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋６；」をプログラム命令群Ｇ＿２＿ＩＮＶとする。【０１４６】
＜プログラム命令群Ｇ＿４の生成＞
プログラム命令群Ｇ＿４は、ブロックＢ２の出口写像情報Ｆ４の写像を行う追加プログラム命令群である。
プログラム命令群Ｇ＿４の生成を説明する。
写像情報Ｆ４「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋７；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋２１；」の、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換え、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘに置換える。【０１４７】
置換えによってできた「ｐｍ＿ａ＝ｐｍ＿ａ＋７；  ｐｍ＿ｂ＝ｐｍ＿ｂ＋５；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋２１；」をプログラム命令群Ｇ＿４とする。
＜変数の置換え＞
ブロックＢ２に含まれる変数の置換えを説明する。
変数の置換えは、代入式の左辺に変数（代入によって値が決まる変数）がある場合と、右辺に変数（代入の値を決める）がある場合とで異なった変換方法によって行う。なお、右辺と左辺の両方に変数がある場合には、右辺に変数がある場合の変換と、左辺に変数がある場合の変換の両方を施す。【０１４８】
ここで、左辺と右辺の具体例を示すと、ブロックＢ２における「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」においては、左辺とは「ｐｍ＿ｂ」であり、右辺は「ｐｍ＿ｂ＊８；」である。
以下、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を置換え対象プログラム命令とし、左辺の変数の置換えと右辺の変数の置換えとを説明する。
＜左辺の変数がある場合の置換え＞
プログラム命令の左辺に変数が含まれている場合には、その変数に対する置き換えを行う。このような変換を行うのは、各プログラム命令の演算結果に出口写像情報を反映させる必要があるからである。【０１４９】
左辺の変数ｐｍ＿Ｘを置換える場合、そのブロックの出口写像情報Ｆ＿ＯＵＴにおいて、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式を全て見つける。
ここで、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が見つからなかった場合、そのプログラム命令に対しては変換の必要がないため、何も変換を行わない。
本具体例では、式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」の左辺の変数が「ｐｍ＿ｂ」であり、ブロックＢ２の出口写像情報がＦ４であることから、ｐｍ＿ｂ＿ｂｅｆｏｒｅを含む式「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；」が見つかることとなる。【０１５０】
次に、見つけた式のｐｍ＿Ｘ＿ｂｅｆｏｒｅを置換え対象プログラム命令の右辺の内容に置換える。ここでは、ｐｍ＿ｂ＿ｂｅｆｏｒｅを「（ｐｍ＿ｂ＊８）」に置換え、「ｐｍ＿ｂ＿ａｆｔｅｒ＝（ｐｍ＿ｂ＊８）＋５；」とする。
その後、「ｐｍ＿ｂ＿ａｆｔｅｒ」を変数「ｐｍ＿ｂ」に変換することにより、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」という式が得られる。【０１５１】
この式は、もともとの式の演算結果に対して、出口写像「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；」を反映させた式である。すなわち、もともとの式「ｐｍ＿ｂ＊８」に対して、出口写像情報の影響である「＋５」を加えた式になる。
なお、上述の例において、左辺の変数がｐｍ＿Ｘ（Ｘ＝ａ，ｂ，ｃ）であって、写像情報にｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が複数ある場合には、対象プログラム命令を、それら複数の式からなるプログラム命令に置換え、次に、それぞれの式のｐｍ＿Ｘ＿ｂｅｆｏｒｅを置換え対象プログラム命令の右辺の内容に置換える。【０１５２】
以上が、左辺に変数がある場合の置換えである。
＜右辺の変数がある場合の置き換え＞
プログラム命令の右辺に変数が含まれている場合には、その変数に対する置き換えを行う。
このような変換を行うのは、プログラム命令の右辺に含まれている変数は入口写像による変換が行われた状態の変数であるので、もともとの式で演算を行っても適切な計算結果が得られないためである。すなわち、プログラム命令の右辺に含まれている変数から入力写像の影響を消すことにより、適切な結果が得られるような式に修正する。【０１５３】
以下の例では説明では、上述した左辺に変数がある場合の置き換えにおいて生成された「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」の右辺の変数を置換える例を示す。
まず、ブロックＢ２の出口写像情報Ｆ４の逆写像Ｆ４＿ＩＮＶを上述した方法で生成する。
ここでは、Ｆ４＿ＩＮＶは、「ｐｍ＿ａ＿ｂｅｆｏｒｅ＝ｐｍ＿ａ＿ａｆｔｅｒ−７；  ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−５；  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＝ｐｍ＿ｃ＿ａｆｔｅｒ−２１」となる。【０１５４】
次に、プログラム命令中の、右辺の変数ｐｍ＿Ｘをｐｍ＿Ｘ＿ｂｅｆｏｒｅに置換える。すなわち、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」を「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」に置き換える。
次に、Ｆ４＿ＩＮＶ中から、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式を見つける。ここで、Ｆ４＿ＩＮＶ中から、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が見つからなかった場合は、変数ｐｍ＿Ｘに対応する入口写像情報がない、すなわち、変数ｐｍ＿Ｘは特に変換されていない状態であるので、置き換えた式中のｐｍ＿Ｘ＿ｂｅｆｏｒｅを変数ｐｍ＿Ｘに戻して処理を終了する。【０１５５】
ここでは、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」の右辺に「ｐｍ＿ｂ＿ｂｅｆｏｒｅ」が含まれているため、これに対応する「ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−５；」が見つかる。
続いて、見つかった式に基づき、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘ＿ａｆｔｅｒを使った式に置換える。すなわち、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」を「ｐｍ＿ｂ＝（（ｐｍ＿ｂ＿ａｆｔｅｒ−５）＊８）＋５；」に置き換える。【０１５６】
最後に、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換える。すなわち「ｐｍ＿ｂ＝（（ｐｍ＿ｂ＿ａｆｔｅｒ−５）＊８）＋５；」を「ｐｍ＿ｂ＝（（ｐｍ＿ｂ−５）＊８）＋５；」に置き換える。
なお、右辺にｐｍ＿ｂ＿ｂｅｆｏｒｅを含むプログラム命令が複数ある場合には、それぞれのｐｍ＿ｂ＿ｂｅｆｏｒｅを（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。【０１５７】
また、一つのプログラム命令に、ｐｍ＿ａ＿ｂｅｆｏｒｅとｐｍ＿ｂ＿ｂｅｆｏｒｅが含まれる場合は、ｐｍ＿ａ＿ｂｅｆｏｒｅを（ｐｍ＿ａ＿ａｆｔｅｒ−７）に、ｐｍ＿ｂ＿ｂｅｆｏｒｅを（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。例えば、ｐｍ＿ｂ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＊ｐｍ＿ｂ＿ｂｅｆｏｒｅは、ｐｍ＿ｂ＝（ｐｍ＿ａ＿ａｆｔｅｒ−７）＊（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。【０１５８】
以上により生成した「ｐｍ＿ｂ＝（（ｐｍ＿ｂ−５）＊８）＋５；」が右辺の変数を置換えた結果となる。このような変換により、入力写像情報が示す「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５」という変換が「ｐｍ＿ｂ−５」により打ち消される。
なお、定数同士の演算は予め行うことができるので、最終的には定数をまとめた式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８−３５；」とすることができる。【０１５９】
以上が、ブロックに含まれる変数の置換えとなる。
＜実施形態３の効果＞
実施の形態３では、変数の役割をプログラムの途中で置換える難読化の一例を示した。この難読化方法は以下の３点を特徴とする。
（イ）コントロールフローの始点となるブロックＢ２の入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てている（写像対応表生成部５３３０の処理参照）。
（ロ）各ブロックに、変数の置換えが入口写像情報Ｆ＿ＩＮで示す置換えであった場合に、出口写像情報Ｆ＿ＯＵＴに示す変数の置換えを行う機能が追加されている（ブロック変換部５４００の処理参照）。
（ハ）ブロックＢ５のような複数の分岐元（ブロックＢ２、ブロックＢ４）を持つブロックの全ての分岐元の出口写像情報は、分岐先のブロック（ブロックＢ５）の入口写像情報と等しい（属性情報割当表１８００参照）。【０１６０】
以上、３点の特徴により、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されても、各ブロックに分岐が発生した際、変数の置換えは、そのブロックの入口写像情報に示す変数の置換えとなる。
このような難読化により、プログラムの様々な位置で変数の役割が置換わり、プログラムの解析を困難にすることができる。また、ブロック毎に、変数の役割が替わることにより、あるブロックでの変数が、他のブロックでどのような役割の変数であるかの解析が困難になる。
＜実施形態４＞
＜概要＞
実施形態１〜３が、対象プログラムにプログラム命令を追加したり、変数の役割を入れ替えて、すなわち変数の値を変えたりすることで難読化プログラムを生成し、ソフトウェアの機密性を確保していたのに対し、本実施形態では、ブロックを暗号化することにより機密性を確保するものである。【０１６１】
すなわち、本実施形態では、プログラムはブロック毎に暗号化され、外部メモリに記憶されているが、全ブロックが同一の暗号鍵で暗号化されていない点に1つの特徴がある。すなわち、１つのブロックを解析するためには、そのブロックの暗号鍵を求める必要がある事となり、解析に時間を要することと成る。
さらに、実行時に次に実行するブロックを復号化することから、ブロック単位でのみ平文が内部メモリに展開されることとなる。すなわち、メモリ上の平文が少ないため、プログラム全体を解析することをより困難とすることができる。【０１６２】
ここでは、実施形態３との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表６９００を図２３に示す。
写像対応表６９００は、ＩＤ１９１０と写像情報６９２０とで構成され、ＩＤ１９１０は実施形態３と同様に、写像情報６９２０の識別子である。【０１６３】
すなわち、実施形態３の写像対応表５９００（図２０参照）では、属性に応じて、変数の値が、どの様な演算が施された値であるかが決まったが、本実施形態では、属性に応じて、ブロックを暗号化する暗号鍵が決まることになる。
＜構成＞
図２４は、実施形態４にかかるプログラム難読化装置６０００の構成例を示すブロック図である。【０１６４】
実施形態３のプログラム難読化装置５０００の構成（図２１参照）と異なる点は、以下の２点である。
１点目は、写像情報生成部６４００の写像対応表生成部６３３０が生成する写像の内容が異なる点である。２点目は、写像の内容が異なることによるブロック変換部６４００で追加するプログラム命令群の生成方法が異なる点である。加えて、ブロック変換部６４００では暗号化も行い難読化プログラム３２００を生成する。【０１６５】
＜動作＞
以下、写像情報生成部６４００の写像対応表生成部６３３０、ブロック変換部６４００の各処理について説明する。他の動作は、対象プログラムをブロックに分割し、各ブロックに入口属性と出口属性を設定することは、実施形態３と同様である（図１６等参照）。
＜写像情報生成部６４００の写像対応表生成部６３３０の処理＞
本実施形態の写像対応表６９００を図２３に示す。【０１６６】
写像対応表６９００は、ＩＤ１９１０と写像情報６９２０とで構成され、ＩＤ１９１０は実施形態１と同様に、写像情報６９２０の識別子である。
写像情報６９２０は、暗号鍵の値を示すものである。例えば、属性情報Ｆ１は、「Ｋｅｙ＝３」である。
本実施形態では、各属性に対応する暗号鍵の値は、予め決めてあるものとする。なお、写像対応表生成時にランダムに作成することとしてもよい。【０１６７】
＜ブロック変換部の処理＞
以下、本実施形態のブロック変換部の処理について、図２５と図２６を用いて説明する。
図２５は、変換後ブロックを示す図であり、図２６は、ブロック変換部の処理を示すフローチャートである。本実施形態では、この変換後ブロックを暗号化して、難読化プログラムを生成する。【０１６８】
図２４のブロックを参照しながら、図２５のフローチャートに基づいてブロック変換部の処理について説明する。
まず、対象プログラムに復号化関数「decrypt」のプログラムを追加する（ステップＳ６１０、図２５：復号化プログラム６４０９参照）。
この復号化関数は、暗号化するブロックの識別子である「ブロックＩＤ」と、暗号鍵「ｋｅｙ」とを引数とし、「ブロックＩＤ」で特定されるブロックを「ｋｅｙ」で暗号化する機能を有する。なお、ここではブロックの識別子を指定しているが、ブロックの開始アドレスと終了アドレスとを指定することとしてもよく、ブロックが特定できればよい。【０１６９】
次に、各ブロックに、各ブロックの次に実行するブロック（以下、「次ブロック」という。）を復号するためのプログラム命令を追加する。図２５における、プログラム命令群６４０１〜６４０４である。本実施形態では、最後のブロックＢ５には（ステップＳ６１５：ＹＥＳ）次に実行するブロックは存在しないことから、プログラム命令を追加しないものとする。最後のブロックでない場合は（ステップＳ６１５：ＮＯ）、以下の次ブロックを復号化するようなプログラム命令群を追加する。【０１７０】
追加するプログラム命令群では、復号化関数を使用して次ブロックを復号化するが、その復号化関数に指定する「ｋｅｙ」、すなわち、復号鍵には、出口写像情報のｋｅｙを設定する。
最初のブロックでは、出口写像情報の値を「ｋｅｙ」に設定する（ブロックＢ１：プログラム命令群６４０１の1行目参照）。例えば、最初のブロックであるブロックＢ１の出口写像情報は「２」であるので、写像情報Ｆ４「ｋｅｙ＝４；」（図２３参照）の「４」を設定する。【０１７１】
また、他のブロックでは、出口写像情報を入口写像情報から求めるプログラム命令を追加する（ステップＳ６２０）。
例えば、ブロック２では、入口写像情報が「２」、出口写像情報が「４」であり、ｋｅｙはそれぞれ「４」、「５」である（図２３参照）。従って、「４」から「５」を求める式、「ｋｅｙ＝ｋｅｙ＋１；」を追加する（ブロックＢ２：プログラム命令群６４０２の1行目参照）。【０１７２】
その後に、もとからある分岐命令に、次に実行するブロックの「ブロックＩＤ」と「ｋｅｙ」とを復号関数の引数に設定したプログラム命令を追加したプログラム命令群を追加する（ステップＳ６３０）。
例えば、ブロックＢ２には、「ｄｅｃｒｙｐｔ（Ｂ５、ｋｅｙ）；ｇｏ  ｔｏ  ｌａｂｅｌＥ；」を追加する（ブロックＢ２：プログラム命令群６４０２の２行目参照）。ここで「Ｂ５」は、ブロックＢ５のブロックＩＤとする。【０１７３】
その後、ブロックを、入口写像情報で示される暗号鍵で暗号化する（ステップＳ６４０）。
例えば、ブロックＢ２は、プログラム命令群６４０２を追加した後、入口写像情報「２」、即ち「Ｋｅｙ＝４」で暗号化する。
すべてのブロックに、ステップＳ６２０〜ステップＳ６４０の処理を行う（ステップＳ６５０）。【０１７４】
本実施形態の難読化プログラムでは、その実行の際には、メモリ上には実行されているブロックのみが平文として存在することとなり、対象プログラムの全体を把握するのが困難となり、プログラムの解析を困難とすることとなる。
＜補足＞
以上、本発明に係るプログラム難読化装置について実施形態に基づいて説明したが、このプログラム難読化装置を部分的に変形することもでき、本発明は上述の実施形態に限られないことは勿論である。即ち、
（１）実施形態では、第一のブロックと第二のブロックから第三のブロックに分岐がある場合には、第一のブロックの出口写像情報と、第二のブロックの出口写像情報と、第三のブロックの入口写像情報は同じ写像情報としたが、第一のブロックの出口写像情報と、第二のブロックの出口写像情報は別の写像であってもよい。【０１７５】
例えば、実施形態１においてブロックＢ２の出口写像情報を「ｐｍ＿０＝１２；ｐｍ＿１＝７；」とし、ブロックＢ４の出口写像情報を「ｐｍ＿０＝４、ｐｍ＿１＝１３；」とし、ブロックＢ５の入口写像情報を「ｐｍ＿０＝１２；ｐｍ＿１＝７；」と「ｐｍ＿０＝４、ｐｍ＿１＝１３；」の二つとしてもよい。
この時ブロックＢ５の入口写像情報は、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、（１２、７）または（４、１３）のいずれかに対応させる写像を示すこととなる。【０１７６】
この時、ブロックＢ５に追加する処理は「（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）＝（１２、７）、（４、１３）」を「（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）＝（１３、２１）」に対応させる写像であり、例えば、追加プログラム命令群「ｐｍ＿０＝（ｐｍ＿０−１２）＊（ｐｍ＿０−４）＋１３；ｐｍ＿１＝（ｐｍ＿１−７）＊（ｐｍ＿１−１３）＋２１；」や「ｐｍ＿０＝３＊（ｐｍ＿０−１２）＊（ｐｍ＿１−１３）＋１３；ｐｍ＿１＝４＊（ｐｍ＿０−４）＊（ｐｍ＿１−７）＋２１；」を追加することとなる。【０１７７】
このような構成により、不正解析者が何らかの解析で第一のブロックの出口写像を知ることができたとしても、第二のブロックの出口情報は知ることができず、解析を困難にできる。
（２）実施形態１における追加変数は、プログラムの引数としてもよい。
引数とした場合は、関数ｆｕｎｃの呼び出し元も変更する必要がある。【０１７８】
例えば、呼び出し元が「ｆｕｎｃ（ａ、ｂ）；」で、追加変数の初期値が「０」「１」である場合には、呼び出し元を「ｆｕｎｃ（ａ、ｂ、０、１）；」に変更する。
なお、呼び出し元を含むプログラムにおける追加変数の初期値を難読化するために、呼び出し元をさらに本難読化手法を用いて難読化しても構わない。
このような構成により、不正解析者が関数ｆｕｎｃを局所的に解析しても、追加変数の初期値を知ることが困難になる。
（３）実施形態２および実施形態３において、コントロールフローの始点となるブロックの入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てているが、異なる変数としてよい。【０１７９】
例えば、実施形態２のブロックＢ２の入口写像情報Ｆ１は、「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」としているが、「ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」としてもよい。【０１８０】
このように他の写像とした場合は、関数ｆｕｎｃの呼び出し元も変更する必要がある。
例えば、呼び出し元が「ｆｕｎｃ（ａ、ｂ、ｃ）；」である場合には、写像情報Ｆ１に基づき、呼び出し元を「ｆｕｎｃ（ｂ、ａ、ｃ）；」に変更する。
なお、呼び出し元を含むプログラムを難読化するために、呼び出し元のプログラムをさらに本難読化手法を用いて難読化しても構わない。【０１８１】
このような構成により、不正解析者が関数ｆｕｎｃを局所的に解析したとしても、変数の置換えの初期値を知ることが困難になる。
（４）実施形態において、写像情報を、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）をｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）に対応させる写像を示したが、サイズの異なる他の変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）に対応させる写像であっても構わない。【０１８２】
このような構成により、追加するプログラム命令群に例えば掛け算があったとしてもオーバーフローの発生を回避することができる。
よって、追加するプログラム命令群を構成するプログラム命令のバリエーションを増やすことができ、ブロックに含まれるプログラム命令群のうち、どのプログラム命令が追加プログラム命令であり、どのプログラム命令がブロックに元々含まれていたプログラム命令であるかを判断することを困難にすることができる。【０１８３】
例えば、実施形態３において、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）を１６ｂｉｔのｉｎｔ型変数、ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）を３２ｂｉｔのｌｏｎｇ型変数として、プログラムに変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）を追加する。
この場合、例えば、写像情報Ｆ２を「ｐｍ＿ｄ＿ａｆｔｅｒ＝（ｌｏｎｇ）ｐｍ＿ａ＿ｂｅｆｏｒｅ＊３−４；」とし、追加プログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝（ｐｍ＿ｄ＋４）／３；」としてもよい。【０１８４】
また、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）を格納する型自体を変えても構わない。
例えば、実施形態３において、変数宣言「ｆ（ｉｎｔ  ｐｍ＿ａ、ｉｎｔ  ｐｍ＿ｂ、ｉｎｔ  ｐｍ＿ｃ）」を「ｆ（ｌｏｎｇ  ｐｍ＿ａ、ｌｏｎｇ  ｐｍ＿ｂ、ｌｏｎｇ  ｐｍ＿ｃ）」として、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＊３−４；」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝（ｐｍ＿ａ＋４）／３；」としてもよい。
（５）実施形態において、写像情報を、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）をｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）に対応させる写像を示したが、他の変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）に対応させる写像であっても、他の変数を含むｐｍ＿Ｙ（Ｙ＝ａ、ｂ、ｃ、ｄ、ｅ、ｆ）に対応させる写像であっても構わない。【０１８５】
例えば、実施形態３において、プログラムに変数「ｐｍ＿ｄ、ｐｍ＿ｅ、ｐｍ＿ｆ」を追加し、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ／３；ｐｍ＿ｄ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ％３；」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝ｐｍ＿ａ＊３＋ｐｍ＿ｄ；」としてもよい。
このような構成により、追加するプログラム命令群を構成するプログラム命令のバリエーションを増やすことができ、ブロックに含まれるプログラム命令群のうち、どのプログラム命令が追加プログラム命令であり、どのプログラム命令がブロックに元々含まれていたプログラム命令であるかを判断することを困難にすることができる。
（６）実施形態３において、写像情報は「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋１４；ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋１２；ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ−６；」で示されるように、一つの変数（例えば、ｐｍ＿ａ＿ｂｅｆｏｒｅ）の値を用いて１つの変数（例えばｐｍ＿ａ＿ａｆｔｅｒ）を算出する写像を示したが、複数の変数を用いて複数の変数を算出する写像であっても構わない。【０１８６】
例えば、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋ｐｍ＿ｂ＿ｂｅｆｏｒｅ；ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ−ｐｍ＿ｂ＿ｂｅｆｏｒｅ」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｔｍｐ＝ｐｍ＿ａ；ｐｍ＿ａ＝（ｐｍ＿ａ＋ｐｍ＿ｂ）／２；ｐｍ＿ｂ＝（ｔｍｐ−ｐｍ＿ｂ）／２；」としても構わない。【０１８７】
このような構成により、変数の役割の置き換えのバリエーションを増やすことができ、解析を困難にすることができる。
（７）実施形態において、写像情報はランダムに生成する場合を示したが、ブロックに含まれるプログラム命令に基づいて写像情報を生成する構成であっても構わない。
例えば、実施形態１において、ブロックＢ５は秘密情報「１２３」を含む。【０１８８】
この時、ブロックＢ５の出口写像情報における「ｐｍ＿０＿ａｆｔｅｒ」の値を秘密情報の値とし、出口写像情報を「ｐｍ＿０＿ａｆｔｅｒ＝１２３；ｐｍ＿１＿ａｆｔｅｒ＝３１；」としてもよい。
この時、ブロック変換部１４００で、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」を「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０＋ｐｍ＿ｃ；」とすれば、適切な処理結果が得られるようなプログラムに難読化することができる。【０１８９】
これにより、ランダムに生成した写像情報からプログラム内で用いる値を算出する処理が省けるので、秘密情報を算出する処理を変換したことによる難読化後のプログラムサイズの増加、実行時間の増加を減らすことができる。
（８）実施形態１において、追加変数が２つの場合を示したが、追加変数はいくつであっても構わない。【０１９０】
追加変数の数を少なくすれば、難読化後のプログラムのサイズを小さく、実行速度を早くすることができ、多くすれば、難読化の効果を大きくすることができる。
（９）実施形態２および実施形態３において、変数の置換え等を行う変数が３つの場合を示したが、置換えを行う変数はいくつであっても構わない。
また、どの変数を置換えるか等をユーザや外部の装置、呼び出し元プログラム等が指定する構成であっても構わない。
（１０）実施形態３では、写像の一例を示したが、逆写像を有する他の写像であっても構わない。【０１９１】
また、逆写像は必要となる度に、写像から生成する場合を示したが、写像対応表生成部５３３０で生成する写像対応表５９００に、逆写像を記載する欄を設ける構成であっても構わない。
これにより、一度逆写像を生成すれば、それ以降の同一の逆写像の生成が必要なくなるので、難読化処理を高速化することができる。【０１９２】
また、写像情報Ｆ＿Ｘに対応して追加するプログラム命令群Ｆ＿Ｘ、写像情報Ｆ＿Ｘの逆写像であるＦ＿Ｘ＿ＩＮＶに対応して追加するプログラム命令群Ｆ＿Ｘ＿ＩＮＶを写像対応表に記載する構成であっても構わない。
これにより、同一の写像情報や逆写像情報について、複数回、同様のプログラム命令群を生成する手間が省けるので、難読化処理を高速化することができる。【０１９３】
また、ここで述べた写像、逆写像、追加プログラム命令群Ｆ＿Ｘ、追加プログラム命令群Ｆ＿Ｘ＿ＩＮＶをユーザが指定する構成であっても構わない。
（１１）実施形態では、対象プログラムが、Ｃ言語で作成されているプログラムである場合を示したが、Ｊａｖａ（登録商標）言語、Ｊａｖａ（登録商標）バイトコード、Ｃ＋＋言語、機械語、アセンブリ言語、コンパイラ等の中間言語、ＵＭＬ（Unified Modeling Language）等のモデリング言語等の他のプログラム言語で作成されたものであっても構わない。【０１９４】
また、対象プログラムは、論理回路記述言語等で記述された論理回路の設計データであってもよい。
さらに、実施形態では、Ｃ言語の難読化対象プログラムを難読化してＣ言語の難読化後プログラムを生成することとしているが、難読化後プログラムを機械語として出力する構成であっても構わない。【０１９５】
また、難読化対象プログラムはＣ言語のプログラムでなくＵＭＬで記載された構造であって、難読化後プログラムはＪａｖａ（登録商標）等の言語であっても構わない。
（１２）実施形態において、変数「ｐｍ＿Ｘ」が取りうる値を要素とする集合ＰＭ＿Ｘは、変数の型によって決めるものであっても、予めユーザが指定するものであっても構わない。
（１３）実施形態において、プログラム命令群をブロックの先頭に追加する場合を示したが、それら以外の位置に追加する構成であっても構わない。【０１９６】
例えば、実施形態２におけるプログラム変換部５４００の処理で、追加するプログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；」を、ブロックＢ２に含まれるプログラム命令「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」の後に追加しても構わない。
この場合、追加したプログラム命令群より前のプログラム命令は、ブロックＢ２の入口写像情報に基づき変数の置換えを行い、追加したプログラム命令群よりも後のプログラム命令は、ブロックＢ２の出口写像情報に基づき変数の置換えを行う。【０１９７】
ここでは、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」をブロックＢ２の入口写像情報Ｆ２に対して基づき変数の置換えを行い「ｐｍ＿ｃ＝ｐｍ＿ｃ＊８；」とする。
このような構成にすることによって、追加プログラム命令群が含まれる位置がブロックによって異なるようになり、変換後ブロックを見て、どのプログラム命令が追加プログラム命令であり、どのプログラム命令が元々ブロックに存在していたプログラム命令であるかを解析しにくくすることができる。【０１９８】
また同様に、追加プログラム命令群の途中に元々ブロックに存在していたプログラム命令が挟まれる構成であっても構わない。このようにすることで、どのプログラム命令群が元々ブロックに存在していたものであるかをさらに解析しにくくすることができる。
（１４）実施形態１における秘密ブロック変換部１５００において、置換えを行う秘密情報は、ユーザ等が指定した秘密情報を置換える構成であっても、プログラムに含まれる全ての定数値を置換える構成であっても構わない。【０１９９】
また、プログラムに含まれる定数値を一定の確率で置換える構成であったり、ランダムに選択したものを置換える構成であっても構わない。
このようにすることで、全ての秘密情報を置き換える場合よりも高速に難読化を行うことができる。また、難読化により増加する処理の数を抑えることができるため、難読化後のプログラムの動作も高速化することができる。
（１５）実施形態１では、追加プログラム命令群Ｇ＿１＿２の一例を示したが、（０、１）を（３０、６）に対応させる写像を実現するプログラム命令群であればどのようなものでも構わない。他の写像を実現するプログラム命令群についても同様である。【０２００】
また、追加プログラム命令群の生成の仕方も実施形態に示したやり方に限るものではなく、他のやり方であっても構わない。
すなわち、入力写像情報が与えられた場合に出力写像情報に従った変換が行われるようなプログラム命令群が生成されるのであればどのようなものであっても構わない。
（１６）実施形態１では、写像情報をｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす全ての（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を１点（例えば（０、１））に対応させる写像を示したが、複数の点に対応させる写像であっても構わない。【０２０１】
例えば、写像情報Ｆ２を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（１、２）または（４、５）のいずれかに対応させる写像とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（５、６）または（８、９）とし、追加プログラム命令群Ｇ＿２＿４を例えば、（１、２）を（５、６）に対応させ、（４、５）を（８、９）に対応させる写像を実現するプログラム命令群とする。【０２０２】
この場合、追加プログラム命令群Ｇ＿２＿４は、例えば「ｐｍ＿０＝ｐｍ＿０＋４；ｐｍ＿１＝ｐｍ＿１＋４；」のようなものとなる。
また、追加プログラム命令群が追加変数以外の変数を含む構成であっても構わない。
例えば、写像情報Ｆ２を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（０、１）または（３、４）のいずれかに対応させる写像とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（０、１）または（１、２）のいずれかに対応させる写像とし、追加プログラム命令群Ｇ＿２＿４を例えば、「ｐｍ＿０＝ｐｍ＿０％３＋ｐｍ＿ａ％２；ｐｍ＿１＝ｐｍ＿１％３＋ｐｍ＿ａ％２；」としてもよい。【０２０３】
このように写像情報を用いて特定変数の値を複数の点に対応させる代わりに、集合を用いることとしてもよい。
例えば、写像情報Ｆ２を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（６の倍数、３で割って１余る数）に対応させる集合とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（６で割って１余る数、３で割って２余る数）に対応させる集合とし、追加プログラム命令群Ｇ＿２＿４を例えば、「ｐｍ＿０＝ｐｍ＿０＋１；ｐｍ＿１＝（ｐｍ＿１−１）＊２＋２；」としてもよい。【０２０４】
このような構成を用いれば、追加変数以外の変数の値によって、追加プログラム命令群を実行した後の追加変数の値が替わる。よって、不正解析者が、どの変数が追加変数であって、どの変数が元々プログラムに含まれる変数であるかを解析することが困難になる。
この効果をより具体的に説明する。追加変数以外の変数を使わない場合、不正解析者が、ブロックの出口写像情報、入口写像情報を解析するために、関数の引数の値を変えて、関数ｆｕｎｃを複数回実行し、実行時にメモリに現れる値（ランタイムデータ）を収集し、その差分をとり、不変なデータを抽出することで写像情報の追加変数の値の特定が可能なる。【０２０５】
これに対し、上記の構成を用いれば、追加プログラム命令群を実行した後のｐｍ＿０、ｐｍ＿１は固定の値とならないため、写像情報の解析が困難になる。また、写像情報を格納する変数がどの変数であるかの解析も困難になる。
なお、ランタイムデータを収集する不正解析については、「署名生成ソフトウェアのランタイムデータ探索による耐タンパー性評価  ＳＣＩＳ２００５」に記載されている。【０２０６】
なお、追加変数以外の変数とは、必ずしも難読化対象プログラムに含まれる変数でなくてもよい。例えば、ＲＯＭ、ＲＡＭ、レジスタ、キャッシュ等に保持されている値であっても構わない。
（１７）実施形態１における秘密ブロック変換部１５００の処理において、置換えを行う秘密情報は、例えばプログラムの分岐先のアドレスのようなプログラムの分岐先を示す数値であっても構わない。【０２０７】
例えば、実施形態１における秘密ブロック変換部１５００の処理において、ブロックＢ２の無条件分岐命令「ｇｏｔｏ  ｌａｂｅｌＥ；」を条件分岐命令「ｓｗｉｔｃｈ（２）｛ｃａｓｅ  １：ｇｏｔｏ  ｌａｂｅｌＣ；  ｃａｓｅ  ２  ｇｏｔｏ  ｌａｂｅｌＥ：｝」に置換える。
この条件分岐命令は、難読化対象プログラムに含まれるラベル「ｌａｂｅｌＥ：」「ｌａｂｅｌＣ：」が条件分岐先であり、条件式は、もともとの無条件分岐先「ｌａｂｅｌ  Ｅ；」に対応するｃａｓｅ文の値「２」としたものである。【０２０８】
次に条件式「２」を、秘密ブロック変換部１５００の処理で述べた方法を用いてブロックＢ２の出口写像情報に基づき追加変数を用いたプログラム命令に置換える。
さらに、実施形態１では、秘密情報を式に置き換えているが、プログラム命令を追加するだけでもよい。
例えば、実施形態１では、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」を「ｐｍ＿ｂ＝ｐｍ＿ｂ＊（３＊ｐｍ＿０＋４＊ｐｍ＿１−４０）＋ｐｍ＿ｃ；」に置き換えているが（図１３、図１４参照）、１プログラム命令を追加することとしてもよい。【０２０９】
具体的には、「ｐｍ＿０」は、ブロックＢ５の出口属性「１０」であり、「ｐｍ＿０＝１３」であるので、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０／１３；」を追加して、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０／１３  ；  ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」としてもよい。
このような構成により、プログラムの実行順序の解析を困難にすることができる。
（１８）各部は、必ずしも独立した部である必要はなく、複数の部が提供する機能を組み合わせた部とする構成であっても構わない。
（１９）実施形態１では、難読化対象プログラムに変数を追加する変数追加手段がある構成を示したが、追加変数の替わりに、難読化対象プログラムにおいて使われていない変数を使う構成であっても構わない。
（２０）実施形態における、ブロック変換部の処理において、入口写像情報と出口写像情報が同じ写像情報であるブロックには、追加プログラム命令を追加しない構成であっても構わない。【０２１０】
そのような構成にすることで、難読化後プログラムのサイズを削減し、実行時間を短縮することができる。
また、属性情報割当表１８００において、異なる属性を同一の属性に置換えてもよい。例えば、実施形態で用いた属性情報割当表１８００の属性１８３１「４」を「２」としてもよい（図９参照）。ブロックＢ２出口属性、ブロックＢ４出口属性およびブロックＢ５入口属性の３つである。【０２１１】
このような構成を用いると、入口写像情報と、出口写像情報が同一となるブロックが増え、さらに難読化後のプログラムのサイズの削減、実行時間の短縮を行うことができる。
（２１）本発明は、実施形態１と実施形態３を組み合わせた構成であっても構わない。
このような構成を用いると、いずれの変数が追加変数であり、いずれの変数が元々プログラムに含まれる変数であるかの解析が困難になる。【０２１２】
また、実施形態１と実施形態２、実施形態４、変形例（補足（１）等）との組み合わせであってもよい。
（２２）実施形態では、難読化対象プログラムを基本ブロックに分割する構成を示したが、その他の分割の仕方であっても構わない。
例えば、基本ブロックをさらに複数のブロックに分割してもよい。例えば、基本ブロックが「ａ＝１；ａ＝ａ＊２；ａ−３；」である場合に、それぞれのプログラム命令をブロックとし、「ａ＝１；」「ａ＝ａ＊２；」「ａ−３；」をそれぞれブロックする。その場合、「ａ＝１；」のブロックから「ａ＝２；」のブロックへは分岐があると見なして、コントロールフローを生成する。このようにすることにより、基本ブロックよりもさらに細かい単位で追加プログラム命令群を入れることができるため、より解析を困難にすることができる。【０２１３】
また、例えば、基本ブロックとは無関係にブロックを生成しても構わない。
その場合、追加プログラム命令は、そのブロックにおける最後の合流点よりも後であって、最初の分岐点よりも前に追加する。もし、そのブロックにおける最後の合流点よりも後であって、最初の分岐点よりも前であるプログラム命令群が１つもない場合には、そのブロックの入口写像情報と出口写像情報とは同じ写像情報とする。【０２１４】
なお、分岐点とは分岐命令（条件分岐命令および無条件分岐命令）がある位置であり、合流点とは分岐命令によって分岐する分岐先の位置である。
（２３）実施形態においるブロック変換部１４００の処理では、プログラム命令を追加することによって、ブロックに機能を追加する構成を示したが、必ずしもこのような構成でなくとも構わない。【０２１５】
例えば、ブロックを構成するプログラム命令のうちのいくつかの命令であるプログラム命令群１を取り除き、このプログラム命令群１と追加する機能の両方の処理を行うプログラム命令群を追加する構成であっても構わない。
例えば、実施形態２において、ブロックＢ２からプログラム命令「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を取り除き、プログラム命令群Ｄ「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ＊８；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；」を追加する構成であっても構わない。【０２１６】
ここで、プログラム命令群Ｄは、変換後ブロックＢ２のプログラム命令群  「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；  ｐｍ＿ａ＝ｐｍ＿ａ＊８；」（図１７参照）の２番目のプログラム命令「ｐｍ＿ａ＝ｐｍ＿ｃ；」と５番目のプログラム命令「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」をまとめて行う処理に置換えたプログラム命令群である。
（２４）上記の実施の形態では、写像情報の基づいた変数の置き換え等を例として挙げたが、これに限られるものではない。【０２１７】
上記の実施の形態では、ブロック間で引き継ぐ秘密情報算出用の変数等について、ブロックから出る時の値と次のブロックに入る時の値とを揃え、各ブロックから出力される時点での値が次のブロックの入力として期待される値となるような範囲で各ブロックを難読化する等しているが、同様の性質を持つ難読化変換も本発明に含まれる。
例えば、実施形態４のように、分岐先のブロックを暗号化し、分岐元のブロックへそのブロックを復号する処理を追加するなどしてもよい。【０２１８】
また、分岐先のブロックにブロック中の命令の偽装を行う変換を施し、分岐元へその偽装の解除を行う処理を追加するなどしてもよい。
すなわち、本発明は、分岐元のブロックと分岐先のブロックとで相殺しあうような性質を有する難読化を施すことによって、プログラムの制御構造に関わらない難読化を行うことを可能とするものである。
（２５）上記の各装置は、具体的には、マイクロプロセッサ、ＲＯＭ、ＲＡＭ、ハードディスクユニット、ディスプレイユニット、キーボード、マウスなどから構成されるコンピュータシステムである。前記ＲＡＭまたはハードディスクユニットには、コンピュータプログラムが記憶されている。前記マイクロプロセッサが、前記コンピュータプログラムにしたがって動作することにより、各装置は、その機能を達成する。ここでコンピュータプログラムは、所定の機能を達成するために、コンピュータに対する指令を示す命令コードが複数個組み合わされて構成されたものである。
（２６）上記の各装置を構成する構成要素の一部または全部は、１個のシステムＬＳＩ（Large Scale Integration：大規模集積回路）から構成されているとしてもよい。システムＬＳＩは、複数の構成部を１個のチップ上に集積して製造された超多機能ＬＳＩであり、具体的には、マイクロプロセッサ、ＲＯＭ、ＲＡＭなどを含んで構成されるコンピュータシステムである。前記ＲＡＭには、コンピュータプログラムが記憶されている。前記マイクロプロセッサが、前記コンピュータプログラムにしたがって動作することにより、システムＬＳＩは、その機能を達成する。
（２７）上記の各装置を構成する構成要素の一部または全部は、各装置に脱着可能なＩＣカードまたは単体のモジュールから構成されているとしてもよい。前記ＩＣカードまたは前記モジュールは、マイクロプロセッサ、ＲＯＭ、ＲＡＭなどから構成されるコンピュータシステムである。前記ＩＣカードまたは前記モジュールは、上記の超多機能ＬＳＩを含むとしてもよい。マイクロプロセッサが、コンピュータプログラムにしたがって動作することにより、前記ＩＣカードまたは前記モジュールは、その機能を達成する。このＩＣカードまたはこのモジュールは、耐タンパ性を有するとしてもよい。
（２８）本発明は、上記に示す方法であるとしてもよい。また、これらの方法をコンピュータにより実現するコンピュータプログラムであるとしてもよいし、前記コンピュータプログラムからなるディジタル信号であるとしてもよい。
（２９）また、本発明は、前記コンピュータプログラムまたは前記ディジタル信号をコンピュータ読み取り可能な記録媒体、例えば、フレキシブルディスク、ハードディスク、ＣＤ−ＲＯＭ、ＭＯ、ＤＶＤ、ＤＶＤ−ＲＯＭ、ＤＶＤ−ＲＡＭ、ＢＤ（Ｂｌｕ−ｒａｙ  Ｄｉｓｃ）、半導体メモリなどに記録したものとしてもよい。また、これらの記録媒体に記録されている前記ディジタル信号であるとしてもよい。
（３０）また、本発明は、前記コンピュータプログラムまたは前記ディジタル信号を、電気通信回線、無線または有線通信回線、インターネットを代表とするネットワーク、データ放送等を経由して伝送するものとしてもよい。
（３１）また、本発明は、マイクロプロセッサとメモリを備えたコンピュータシステムであって、前記メモリは、上記コンピュータプログラムを記憶しており、前記マイクロプロセッサは、前記コンピュータプログラムにしたがって動作するとしてもよい。
（３２）また、前記プログラムまたは前記ディジタル信号を前記記録媒体に記録して移送することにより、または前記プログラムまたは前記ディジタル信号を前記ネットワーク等を経由して移送することにより、独立した他のコンピュータシステムにより実施するとしてもよい。【０２１９】
＜従来技術の詳細および課題＞
図２７は、従来の難読化方法の例を示すプログラム例である。
＜オリジナルプログラム＞
難読化前のオリジナルプログラムを図２７（ａ）に示す。このプログラムにおいて、「１２３４」は不正解析者に知られたくない秘密情報９００１である。なお、以下では特に断らない限り、Ｃ言語で記述されたプログラムを例とした説明を行う。【０２２０】
図２７（ａ）に示す難読化前のプログラムでは、このプログラムに含まれる定数を全て収集することで秘密情報９００１の値を絞りこむことができる。すなわち、図２７（ａ）に含まれる定数を収集すると、「１」、「２」、「７」、「５」、「１２３４」が収集できるが、そのうちの一つは秘密情報の値である。よって、不正解析者は、プログラムに含まれる定数を収集するだけで秘密情報の値を５つに絞りこむことができる。【０２２１】
＜秘密情報置換え後プログラム＞
プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換したプログラムを図２７（ｂ）に示す。
このプログラムは、オリジナルプログラム（ａ）に新しい変数「ｃ」を追加し、追加した変数「ｃ」を用いて秘密情報「１２３４」を算出する処理を追加し、秘密情報「１２３４」を「ｃ（９００２）」に置換えることで生成したプログラムである。【０２２２】
この図では、「ｃ＝１；ｃ＝ｃ＊１０＋２；ｃ＝ｃ＊１０＋３；ｃ＝ｃ＊１０＋４；」が秘密情報「１２３４」を算出するプログラム命令群である。
図２７（ｂ）のプログラムでは、プログラムに含まれる定数を全て収集しても秘密情報「１２３４」が直接得られることはない。
よって、図２７（ａ）のプログラムよりも安全性が高い。【０２２３】
しかし、不正解析者がプログラムの処理自体を解析する等して「ａ＝ａ＋ｂ＋ｃ；」の「ｃ」が秘密情報９００１であると判断した場合、秘密情報を算出する処理「ｃ＝１；」「ｃ＝ｃ＊１０＋２；」「ｃ＝ｃ＊１０＋３；」「ｃ＝ｃ＊１０＋４；」を順に実行することでｃ９００２の値が順に「１」、「１２」、「１２３」、「１２３４」となることを解析し、秘密情報の値「１２３４」を解析することができる。【０２２４】
＜秘密情報拡散後プログラム＞
続いて、秘密情報を算出する処理をプログラム中の様々な位置に拡散したプログラムを図２７（ｃ）に示す。このプログラムは、図２７（ｂ）で示した秘密情報置換え後プログラムに含まれる秘密情報を算出するプログラム命令「ｃ＝１；」、「ｃ＝ｃ＊１０＋２；」、「ｃ＝ｃ＊１０＋３；」、「ｃ＝ｃ＊１０＋４；」をプログラム中の様々な位置に拡散したプログラムである。【０２２５】
秘密情報置換え後プログラム図２７（ｂ）では、秘密情報を算出するための処理が一箇所にまとまっていたのに対し、図２７（ｃ）では様々な位置に拡散されたことで、秘密情報を算出する処理を見つけ出すことが困難になる。
また、以上で述べた難読化方法の他にも、非特許文献１には、計算途中の値を記憶する変数のメモリをプログラム実行中に何度か変えることでプログラムの解析が困難になることが述べられている。図２７（ｄ）は、このような難読化の一例として、変数の役割をプログラムの途中で変えるプログラムを示す。【０２２６】
＜変数の役割をプログラムの途中で変えるプログラム＞
変数の役割をプログラムの途中で変えるプログラムを図２７（ｄ）に示す。このプログラムはオリジナルプログラム図２７（ａ）に変数ｄ、ｅを追加し、プログラムの途中に「ｄ＝ａ；ｂ＝ｅ；」を追加して、追加した位置以降の変数「ａ」、「ｂ」をそれぞれ「ｄ」、「ｅ」に置換えたプログラムである。【０２２７】
すなわち、オリジナルプログラムの途中に「ｄ＝ａ；ｂ＝ｅ；」（プログラム命令９００３）を追加して、追加した位置以降のプログラム命令群において変数「ａ」、「ｂ」をそれぞれ「ｄ」、「ｅ」に置換え、「ａ＝ａ＜＜５；ａ＝ａ＊ｂ；ａ＝ａ＋ｂ＋１２３４；ｕｓｅ（ａ）」を「ｄ＝ｄ＜＜５；ｄ＝ｄ＊ｅ；ｄ＝ｄ＋ｅ＋１２３４；ｕｓｅ（ｄ）」としたプログラムである。【０２２８】
このプログラムでは、プログラムの途中から、変数「ａ」、「ｂ」の役割を「ｄ」、「ｅ」が行うことになる。そのため、秘密情報の算出に用いる変数がどれであるのかを追跡しにくくなる。
＜課題＞
プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換し、さらに、そのプログラム命令をプログラム中の様々な場所に拡散することで解析を困難にする方法がある。しかし、制御構造が複雑なプログラムに対して拡散を行うことは困難であるため、不正解析者は特定の箇所を重点的に解析することにより比較的容易に秘密情報を得ることができてしまうという課題がある。以下、この課題を具体的に説明する。【０２２９】
（ａ）オリジナルプログラム
図２８は難読化前のオリジナルプログラムを示す。オリジナルプログラムは関数ｆｕｎｃを含み、関数はプログラム命令群９１１０からなる関数である。また、「１２３」が秘密情報である（プログラム命令９１０１参照）。
このプログラムのコントロールフローを図２９に示す。【０２３０】
コントロールフローは、プログラムにおける分岐や合流といった制御の流れをグラフで表現したものであり、一般に制御フローグラフと呼ばれるものである。コントロールフローの生成は、例えば次の基本ブロック生成ステップと、グラフ生成ステップとからなる。
基本ブロック生成ステップは、難読化対象プログラムから基本ブロックを生成するステップである。基本ブロックとは、１以上のプログラム命令からなるプログラム命令群であって、プログラム命令群の先頭以外では他のブロックから合流せず、プログラム命令群の最後以外では他のブロックへ分岐しないプログラム命令群である。【０２３１】
より詳細には、基本ブロックは、プログラムの入口のプログラム命令（プログラムの一番最初に実行されるプログラム命令）、または、処理が合流するプログラム命令、または、分岐となるプログラム命令の次のプログラム命令を開始プログラム命令とし、次に処理が合流するプログラム命令の一つ前のプログラム命令、または、プログラムの出口の命令（プログラムの一番最後に実行される命令）、または分岐となるプログラム命令を終了プログラム命令とし、開始プログラム命令から終了プログラム命令までに存在するプログラム命令からなるプログラム命令群である。【０２３２】
基本ブロック生成ステップでは、難読化対象プログラムを分割して複数の基本ブロックを生成し、難読化対象プログラムを構成する全てのプログラム命令は、基本ブロック生成ステップにより、いずれかの一つの基本ブロックに含まれるように分割を行う。
グラフ生成ステップでは、次の処理を行う。
基本ブロックのそれぞれをノードと見なし、第一のノードに第二のノードへの分岐命令（ｇｏｔｏ文、ｂｒｅａｋ文、ｃｏｎｔｉｎｕｅ文、ｒｅｔｕｒｎ文による無条件分岐命令、またはｆｏｒ文、ｗｈｉｌｅ文、ｄｏ−ｗｈｉｌｅ文、ｉｆ文、ｓｗｉｔｃｈ文による条件分岐命令のこと）がある場合、または、第一のノードの最後のプログラム命令が無条件分岐命令以外のプログラム命令であって、前記最後のプログラム命令に対応するプログラム上のプログラム命令の一つ後のプログラム命令が対応するプログラム命令が第二のノードであった場合に、第一のノードと第二のノードの間にはエッジが存在すると見なし、ノードとエッジからなるグラフを生成する。【０２３３】
図２９において、ブロック９１１１〜９１１５はプログラムを複数のプログラム命令群に分割したブロックを示す。各ブロックは１以上のプログラム命令からなるプログラム命令群である。また、矢印は制御の流れとエッジを示す。
ブロック９１１１からは２つの矢印が出ているが、デバッガ等でプログラムの実行手順を強制的に変えるなどを行わないような実行時、すなわち、正常系での実行時にブロック９１１１が実行された後に、ブロック９１１２かブロック９１１３のどちらかが実行されることを示す。ブロック９１１５は、秘密情報である値「１２３」を含む。【０２３４】
（ｂ）秘密情報置換え後プログラムのコントロールフロー
図３０は、図２７（ｂ）と同様に、オリジナルプログラム図２７（ａ）に新しい変数「ｃ」を追加し、追加した変数「ｃ」を用いて秘密情報「１２３」を算出する処理を追加し、秘密情報「１２３」を「ｃ」に置換えることで生成したプログラムのコントロールフロー図である。【０２３５】
すなわち、ブロック９２１１中で「ｃ＝１；」と変数ｃの初期化を行い、ブロック９２１５で「ｃ＝ｃ＊１０＋２；ｃ＝ｃ＊１０＋３；」という計算を行わせることにより、変数ｃに「１２３」という値が算出されるようにしている。
（ｃ）秘密情報拡散後プログラムのコントロールフロー
図３０に示した秘密情報を算出するプログラム命令をプログラム中の様々な位置に拡散したプログラムを図３１に示す。【０２３６】
以下、図３０のプログラムから図３１のプログラムのコントロールフローを生成する手順を説明する。
まず、ブロック９２１５に含まれるプログラム命令「ｃ＝ｃ＊１０＋２；」を移動する場所を決める（図３０参照）。
ここで、このプログラム命令は、条件分岐の片側に移動することはできない。このような制限が設けられる理由は、例えば、ブロック９１１４にこのプログラム命令を移動すると、ブロック９１１４が実行されずにブロック９１１２が実行される分岐が起こった場合に、このプログラム命令「ｃ＝ｃ＊１０＋２；」が実行されないためである。この場合、ブロック９２１５におけるｃの値が「１２３」ではなくなってしまうため、適切な演算が行えなくなる。【０２３７】
同様に、このプログラム命令はループの中身に入れることもできない。これは、例えば、ブロック９１１３にこのプログラム命令を移動すると、ブロック９１１３が実行される回数によってこのプログラム命令「ｃ＝ｃ＊１０＋２；」が実行される回数が変わってしまうためである。この場合、「ｃ＝ｃ＊１０＋２；」が２回以上実行されると、ブロック９２１５におけるｃの値が「１２３」と異なる値となってしまい、適切な演算が行えなくなる。【０２３８】
よって、本プログラム例ではｃの値が最終的に「１２３」となることを保証するために、このプログラム命令「ｃ＝ｃ＊１０＋２；」をブロック９３１１に移動することとなる（図３１参照）。同様に「ｃ＝ｃ＊１０＋３；」も同様にブロック９３１１に移動することとなり、図３１に示すコントロールフローのプログラムが生成される。
このように、従来手法では、分岐やループを含むプログラムでは、プログラム命令を移動可能な位置は少なく、結果として、プログラム命令は十分に拡散されずに特定の箇所に集中してしまう。よって、従来手法では、プログラム命令の拡散が困難な箇所（分岐やループ等）以外の箇所を重点的に解析することにより、秘密情報を算出するプログラム命令群を比較的容易に見つけ出すことができてしまうという課題がある。【０２３９】
さらに、非特許文献１では、計算途中の値を記憶する変数のメモリをプログラムの途中で変えることでプログラムの解析が困難になることが述べられている。
しかし、制御構造が複雑なプログラムに対してこの手法を行う際にも、上記と同様の課題がある。以下、この課題を具体的に説明する。
難読化前のオリジナルプログラムは前記と同じく図２８のプログラムであるとする。また、プログラムのコントロールフローは図２９のコントロールフローとなる。このプログラムの途中で変数の役割を置換える。【０２４０】
変数の入れ替えを分岐の片側で行なうことはできない。
例えば、ブロック９１１４の最後に変数の役割を入れ替えるための命令「ｄ＝ａ；ｅ＝ｂ；」を追加した場合、ブロック９１１５に含まれるプログラム命令群「ｌａｂｅｌＥ：  ｂ＊＝ａ＊１２３；ｒｅｔｕｒｎ  ｂ；」において、「ａ」、［ｂ］を「ｄ」、「ｅ」に置換え「ｌａｂｅｌＥ：；  ｅ＊＝ｄ＊１２３；ｒｅｔｕｒｎ  ｅ；」としなければならない。【０２４１】
しかし、このように置換えると、ブロック９１１４が実行されずにブロック９１１５が実行される場合、すなわち、ブロック９１１１の後にブロック９１１２が実行される分岐が行われた場合に、「ｄ＝ａ；ｅ＝ｂ；」が実行されないまま、ブロック９１１５が実行されることになる。
この場合、ｄおよびｅの値がａおよびｂの値と異なってしまうので、正しい演算結果が得られなくなる。よって、プログラム命令を拡散させる際と同様に、分岐の片側で入れ換えを行うことを避け、ブロック９１１１に変数の役割を入れ替えを行う処理を追加することとなる。そのため、変数の役割を入れ替える処理を多数追加しようとしても、このような処理がブロック９１１１に集中してしまうため、処理を見つけ出し易くなってしまうという課題がある。【０２４２】
以上の例に見られるように、従来の難読化方法でプログラムに含まれる処理を複雑にする変換を行っても、プログラムの解析を困難にする難読化の方法として、その制御構造によっては複雑にしにくいものがあるという課題がある。
【産業上の利用可能性】
【０２４３】
本発明は、プログラムを従来技術よりも解析困難なように難読化することができるので、暗号鍵等の秘密情報を扱うプログラムの難読化装置等の分野で有用である。
【図１】
2007091558.tif 000003
【図２】
2007091558.tif 000004
【図３】
2007091558.tif 000005
【図４】
2007091558.tif 000006
【図５】
2007091558.tif 000007
【図６】
2007091558.tif 000008
【図７】
2007091558.tif 000009
【図８】
2007091558.tif 000010
【図９】
2007091558.tif 000011
【図１０】
2007091558.tif 000012
【図１１】
2007091558.tif 000013
【図１２】
2007091558.tif 000014
【図１３】
2007091558.tif 000015
【図１４】
2007091558.tif 000016
【図１５】
2007091558.tif 000017
【図１６】
2007091558.tif 000018
【図１７】
2007091558.tif 000019
【図１８】
2007091558.tif 000020
【図１９】
2007091558.tif 000021
【図２０】
2007091558.tif 000022
【図２１】
2007091558.tif 000023
【図２２】
2007091558.tif 000024
【図２３】
2007091558.tif 000025
【図２４】
2007091558.tif 000026
【図２５】
2007091558.tif 000027
【図２６】
2007091558.tif 000028
【図２７】
2007091558.tif 000029
【図２８】
2007091558.tif 000030
【図２９】
2007091558.tif 000031
【図３０】
2007091558.tif 000032
【図３１】
2007091558.tif 000033
【手続補正書】
【提出日】平成20年7月10日(2008.7.10)
【手続補正１】
【補正対象書類名】特許請求の範囲
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【特許請求の範囲】
【請求項１】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とするプログラム難読化装置。
【請求項２】
前記対象プログラムは、秘密情報を含み、
前記プログラム難読化装置は、更に、前記対象プログラムから、特定変数の値に基づいて前記秘密情報を求める命令を含むブロックを秘密ブロックとして特定するブロック特定手段を備え、
前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられており、
前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項３】
前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックが複数ある場合には、全ての当該ブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項４】
前記生成手段は、更に、前記秘密ブロックの前に実行され得るブロックに、当該ブロックの入口の属性に応じた特定変数の値から、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項５】
前記プログラム難読化装置は、更に、前記対象プログラムに含まれない変数を追加する変数追加手段を備え、
前記特定変数は、前記変数追加手段で追加された変数である
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項６】
ブロックの入口または出口の属性に対応付けられている特定変数の値は複数あり、
前記生成手段は、特定変数が、ブロックの入口の属性に応じた特定変数のいずれかの値から当該ブロックの出口の属性に応じたいずれかの値になるようにする1又は複数の命令を付加する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項７】
前記特定変数は、複数あり、
前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項８】
前記属性には、それぞれ所定の演算が対応付けられており、
前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項２記載のプログラム難読化装置。
【請求項９】
前記属性には、それぞれ複数の特定変数の値の入れ替えが対応付けられており、
前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える処理を行う命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える処理を行う命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１０】
前記属性には、それぞれ特定変数と所定の演算とが対応付けられており、
前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような処理を行う命令を付加し、
前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような処理を行う命令を付加して、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１１】
前記プログラム難読化装置は、更に、ブロックを暗号化する暗号化手段を備え、
前記属性には、それぞれ暗号鍵が対応付けられており、
前記生成手段は、ブロックの出口の属性に対応付けられている暗号鍵で、当該ブロックの出口から実行制御が遷移する他のブロックを復号する処理を行う1又は複数の命令を付加し、前記1又は複数の命令を付加したブロックを、前記暗号化手段に当該ブロックの入口の属性に対応付けられている暗号鍵で暗号化させて、難読化プログラムを生成する
ことを特徴とする請求項１記載のプログラム難読化装置。
【請求項１２】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成される命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を、全ての入口からの実行制御が通る部分に付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とするプログラム難読化装置。
【請求項１３】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定する属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備え、
前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられ、複数のブロックから実行制御が遷移してくるブロックの入口の属性には、遷移元の全てのブロックの出口の属性に対応付けられている値が対応付けられており、
前記生成手段は、１又は複数のブロックに、特定変数が、ブロックの入口の属性に応じた特定変数の値のうちの何れの値からも当該ブロックの出口の属性に応じた値になるようにする処理を行う１又は複数の命令を付加し、難読化プログラムを生成する
ことを特徴とするプログラム難読化装置。
【請求項１４】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置において用いられる難読化方法であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定ステップと、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成ステップと
を備えることを特徴とするプログラム難読化方法。
【請求項１５】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置に難読化処理を行わせるコンピュータプログラムであって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定ステップと、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成ステップと
を備えることを特徴とするコンピュータプログラム。
【請求項１６】
複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置で使用される集積回路であって、
前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、
ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、
1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段と
を備えることを特徴とする集積回路。
【手続補正２】
【補正対象書類名】明細書
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はソフトウェアプロテクションに関するものであり、特に、プログラムの難読化に関する。
【背景技術】
【０００２】
ソフトウェアプロテクションとは、ソフトウェアを改竄、解析、コピー等されることから守ること、すなわち、ソフトウェアの機密性を保持することをいう。
例えば、コピー防止用に、映像コンテンツ等を暗号化する技術がある。しかし、暗号化のプログラムは、秘密情報である暗号鍵を用いて処理を行っており、処理が解析されて暗号鍵が不正解析者に奪われると、暗号化されたコンテンツが復号され、コンテンツが自由に利用できることとなってしまう。
【０００３】
また、画像にウォーターマークを埋め込み、コピーを制御する技術がある。しかし、このようなウォーターマークの検出を行うプログラムの処理／アルゴリズムが不正解析者によって解析されると、その解析結果を元に画像に埋め込まれたウォーターマークを除去するツールを作成される恐れがある。すなわち、画像データへのコピー制御が利かなくなり、自由に元の画像のコピーが出来ることとなってしまう。
【０００４】
このように、ソフトウェアの機密性が保持できなくなることは権利者の保護に欠け、商業的にも損失が大きいなど不都合が多いことから、プログラムの解析を困難にする技術が要望されている。
このような要望に対し、例えば、非特許文献１には、プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換し、さらに、そのプログラム命令をプログラム中の様々な場所に拡散することで解析を困難にする手法が述べられている。
【０００５】
このようなプログラムに含まれる処理を複雑にすること、すなわち、プログラムの難読化は、プログラムの解析に必要な時間を長くすることとなり、結果として、プログラムに含まれる秘密情報の解析を防ぐことが可能になるという効果がある。
【非特許文献１】鴨志田、松本、井上、「耐タンパーソフトウェアの構成手法に関する考察」、ＩＳＥＣ９７−５９
【発明の開示】
【発明が解決しようとする課題】
【０００６】
しかし、このようなプログラムの難読化の手法は、そのプログラムの制御構造によっては複雑にし難い場合がある。
すなわち、分岐やループを多く含む制御構造が複雑なプログラムでは、秘密情報を使用する箇所に至るルートが複数あることとなるが、実行時にどのルートを通ったとしても秘密情報の算出結果が同一でなければならないという制限があるからである。
【０００７】
言い換えれば、秘密情報を算出するための処理は、実行時には必ず通るルートにしか配置できないこととなる。
この場合、不正解析者はこのような箇所、例えば、分岐のないプログラムの入口などを重点的に解析することにより、比較的容易に秘密情報を得ることができてしまうことになる。
【０００８】
そこで、本発明は、制御構造が複雑なプログラムであっても、処理を複雑にする為のプログラム命令を、広範囲に拡散して配置したプログラムを生成するプログラム難読化装置の提供を目的とする。
【課題を解決するための手段】
【０００９】
上記課題を解決する為に、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備えることを特徴とする。
【００１０】
なお、実行制御とは、プログラム実行時に実行され得る複数ルートの選択制御をいう。
【発明の効果】
【００１１】
本発明に係るプログラム難読化装置は、上述の構成を備えることにより、ブロックの出口属性と、そのブロックから実行制御が遷移する遷移先ブロックの入口属性とは同一の属性が設定されることとなり、これらのブロック間で引き継がれる処理の内容は、遷移先ブロックの予定した処理の内容であることが保障される。
従って、遷移先ブロックでは、予定した処理の内容に基づいて、自ブロックの処理を行うことが可能となる。
【００１２】
また、前記対象プログラムは、秘密情報を含み、前記プログラム難読化装置は、更に、前記対象プログラムから、特定変数の値に基づいて前記秘密情報を求める命令を含むブロックを秘密ブロックとして特定するブロック特定手段を備え、前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられており、前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。
【００１３】
これにより、ブロックの出口属性と、そのブロックから実行制御が遷移する遷移先ブロックの入口属性とは同一の属性が設定されることとなり、これらのブロック間で受け渡される特定変数の値は、遷移先ブロックの予定した値であることが保障される。特定変数が属性に応じて決まるからである。
従って、秘密ブロックに実行が遷移する前のブロック内に、特定変数を使用したいかなるプログラム命令を追加したとしても、係るブロックの出口において特定変数が出口属性に応じた値となるならば、秘密ブロックでは、特定変数を用いて秘密情報を求めることが可能となる。
【００１４】
言い換えれば、秘密情報を特定変数から求めるので、秘密情報が直接プログラムの中に現れることが無くなる上、秘密情報を求める式などが秘密情報の位置から離れるので、秘密情報の位置を見つけることが難くなり、結果として、秘密情報が奪われることを回避できる可能性が高くなる。
また、前記生成手段は、前記秘密ブロックに実行制御が遷移するブロックが複数ある場合には、全ての当該ブロックに、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。
【００１５】
これにより、実行時にいずれのルートを通ったとしても、秘密ブロックの入口では特定変数は予定した値となるので、秘密ブロックでは、特定変数を用いて秘密情報を求めることが可能となる。
また、前記生成手段は、更に、前記秘密ブロックの前に実行され得るブロックに、当該ブロックの入口の属性に応じた特定変数の値から、特定変数が当該ブロックの出口の属性に応じた値となるようにする1又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。
【００１６】
これにより、連続して実行されうるブロック同士は、互いに属性を共有し、属性に応じた変換を行うので、全てのブロックに、難読化のためのプログラム命令を付加することできるようになる。
言い換えれば、全てのブロック内に、特定変数を使用したいかなるプログラム命令を追加したとしても、ブロックの出口において特定変数が出口属性に応じた値となるならば、各ブロックでは、入口属性に応じて変換を相殺する処理を加えることができ、難読化前の処理結果を保証することが可能となる。
【００１７】
すなわち、制御構造が複雑なプログラムであっても、全てのブロック内に、プログラム命令を追加することができ、プログラムの解析を困難にすることが出来るようになる。
つまり、従来技術では困難であった複雑な制御構造に対する処理の複雑化が可能となる。
本発明では、少なくともデバッガ等でプログラムの実行手順を強制的に変えるなどを行わないような実行時（以下、「正常系での実行時」という。）には、ブロックに遷移してくる前に加えられた変換を相殺する機能を、そのブロック内に追加することができる。実行制御が遷移するブロック間では属性を共有するため、入口属性に応じた変換が加えられていることが確実だからである。
【００１８】
このため、少なくとも正常系での実行時には、ブロック内でのプログラムの実行結果が変わらないことが保証されるので、付加されたプログラム命令による難読化はプログラムの制御構造に関わらず、プログラム中の多様な箇所に施すことができるのである。
ループを例に挙げると、ループを何周回ることとなっても難読化により付加された処理の影響はループの内部で相殺されるため、ループ箇所から出力される結果は難読化前と同一となる。すなわち、難読化前後でプログラムの出力結果は変化しない。
【００１９】
従って、従来技術では難読化の前後でプログラムの出力結果を同一とするために処理の複雑化を行う箇所を制限していたのに対し、本発明ではこのような制限のない処理の複雑化が可能となる。
また、前記プログラム難読化装置は、更に、前記対象プログラムに含まれない変数を追加する変数追加手段を備え、前記特定変数は、前記変数追加手段で追加された変数であることとしてもよい。
【００２０】
これにより、難読化前のプログラムでは実行使用されない変数を用いて、難読化後プログラムを生成できるので、本来のプログラムの実行に影響を与えずに難読化が可能となり、秘密情報を守る事が出来るようになる。
また、ブロックの入口または出口の属性に対応付けられている特定変数の値は複数あり、前記生成手段は、特定変数が、ブロックの入口の属性に応じた特定変数のいずれかの値から当該ブロックの出口の属性に応じたいずれかの値になるようにする1又は複数の命令を付加することとしてもよい。
【００２１】
これにより、ブロックの入口における特定変数の値が１つではなくなるので、デバッガ等を用いたプログラム実行中の解析をより困難とすることができるようになる。
また、前記特定変数は、複数あり、前記生成手段は、一のブロックに、当該ブロックの出口の属性に応じて、特定変数のうちの１特定変数の値と他の特定変数の値とを入れ替える命令を付加し、前記一のブロックの出口から実行制御が遷移する他のブロックに、当該ブロックの入口の属性に応じて、前記特定変数の値と前記他の特定変数の値とを入れ替える命令を付加して、難読化プログラムを生成することとしてもよい。
【００２２】
これにより、特定変数の役割がブロック毎に異なることとできるので、プログラムの解析をより困難とすることができるようになる。
また、前記属性には、それぞれ所定の演算が対応付けられており、前記生成手段は、一のブロックに、特定変数の値に当該ブロックの出口の属性に対応する所定の演算を施した結果値を、当該特定変数の値とするような命令を付加し、前記一のブロックの出口から実行制御が遷移する他のブロックに、当該特定変数の値に当該ブロックの入口の属性に対応した所定の演算の逆演算を施した結果値を、当該特定変数の値とするような命令を付加して、難読化プログラムを生成することとしてもよい。
【００２３】
これにより、特定変数の値がブロック毎に異なることとできるので、プログラムの解析をより困難とすることができるようになる。
また、前記プログラム難読化装置は、更に、ブロックを暗号化する暗号化手段を備え、前記属性には、それぞれ暗号鍵が対応付けられており、前記生成手段は、ブロックの出口の属性に対応付けられている暗号鍵で、当該ブロックの出口から実行制御が遷移する他のブロックを復号する処理を行う1又は複数の命令を付加し、前記1又は複数の命令を付加したブロックを、前記暗号化手段に当該ブロックの入口の属性に対応付けられている暗号鍵で暗号化させて、難読化プログラムを生成することとしてもよい。
【００２４】
これにより、ブロック毎に異なる鍵で暗号化することができるので、プログラムの解析をより困難とすることができるようになる。
また、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成される命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定し、一のブロックの出口から他のブロックの入口に実行制御が遷移する関係にある当該出口と当該入口とは同一の属性となるように当該決定を行う属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を、全ての入口からの実行制御が通る部分に付加し、難読化プログラムを生成する生成手段とを備えることとしてもよい。
【００２５】
これにより、ブロックをより大きなブロックとしたとしても難読化をすることができるので、難読化にかかる処理速度を短縮することができるようになる。
また、本発明のプログラム難読化装置は、複数ブロックで構成される対象プログラムに基づいて、難読化プログラムを生成するプログラム難読化装置であって、前記ブロックは、順序付けられた複数の命令で構成され、最初の命令以外では実行制御が他のブロックから遷移せず、最後の命令以外では他のブロックに実行制御が遷移しない命令群であり、ブロックにおける実行制御の入口と出口それぞれに対して属性を決定する属性決定手段と、1又は複数のブロックに、当該ブロックの入口又は出口の属性に応じた処理を行う1又は複数の命令を付加し、難読化プログラムを生成する生成手段とを備え、前記属性には、それぞれ１又は複数の特定変数と１又は複数のその値とが対応付けられ、複数のブロックから実行制御が遷移してくるブロックの入口の属性には、遷移元の全てのブロックの出口の属性に対応付けられている値が対応付けられており、前記生成手段は、１又は複数のブロックに、特定変数が、ブロックの入口の属性に応じた特定変数の値のうちの何れの値からも当該ブロックの出口の属性に応じた値になるようにする処理を行う１又は複数の命令を付加し、難読化プログラムを生成することとしてもよい。
【００２６】
これにより、複数ブロックから１つのブロックに実行制御が遷移する場合に、実行制御が遷移する元のブロックの出口属性を全てのブロックで同じとしなくてもよいので、これらブロックの出口における特定変数の値が異なることとなり、プログラムの解析をより困難とすることができるようになる。
【発明を実施するための最良の形態】
【００２７】
＜実施形態１＞
＜概要＞
本発明に係るプログラム難読化装置は、分岐やループを多く含む制御構造が複雑なプログラムであっても、秘密情報を使用する箇所に至る全てのルート上に、処理を複雑にする為のプログラム命令を配置したプログラムを生成することができるものである。
【００２８】
本発明の説明の前に、図２８〜図３１を用いて、従来のプログラム難読化について簡単に説明する。従来のプログラム難読化の手法とその課題についての詳細は、後に説明する。
＜従来のプログラム難読化＞
図２８は難読化前のオリジナルプログラム９１００を示す図であり、プログラム命令群９１１０から成る。秘密情報は、プログラム命令９１０１の「１２３」であるとする。
【００２９】
図２９は、ブロック９１１１〜ブロック９１１５から成るオリジナルプログラム９１００のコントロールフローを示す図である。また、図３０および図３１は、秘密情報を算出するプログラム命令を配置した難読化後のプログラムのコントロールフローを示す図であり、それぞれブロック９２１１〜ブロック９２１５、ブロック９３１１〜ブロック９３１５から成る。
【００３０】
図３０では、オリジナルプログラム９１００に新しい変数「ｃ」を追加し（ブロック９２１１下線部分参照）、追加した変数「ｃ」を用いて秘密情報「１２３」を算出する処理を追加し、秘密情報「１２３」を「ｃ」に置換える（ブロック９２１５下線部分参照）ことで難読化プログラムを生成している。
図３１では、図３０で追加したプログラム命令をプログラム中の様々な位置に拡散したプログラムを示している。
【００３１】
ここでは、このプログラム命令は、条件分岐の片側に移動することはできず、また、ループの中身に入れることもできない。秘密情報「１２３」を置き換えた「ｃ」の値が「１２３」と異なる値となってしまうからである。
よって、本プログラム例では「ｃ」の値が最終的に「１２３」となることを保証するために、プログラム命令はブロック９３１１に移動することとなる。
【００３２】
このように、従来手法では、分岐やループを含むプログラムでは、プログラム命令を移動可能な位置は少なく、結果として、プログラム命令は十分に拡散されずに特定の箇所、すなわち、プログラム命令の拡散が困難な箇所以外の箇所（分岐やループ等に影響を受けない箇所）に集中してしまう。従って、このような特定の箇所を重点的に解析することにより、秘密情報を算出するプログラム命令群を比較的容易に見つけ出すことができてしまう。
【００３３】
本発明に係るプログラム難読化装置は、従来ではプログラム命令の拡散が困難とされていた箇所にも、プログラム命令を配置できるようにしたものである。
以下、本発明の実施形態のプログラム難読化装置について説明する。
本実施形態は、秘密情報を、複数のプログラム命令を実行することによって算出されるように変換する難読化の一例であり、難読化前のプログラム（以下、「対象プログラム」という。）に新たな変数を追加し、秘密情報をかかる変数から算出する式に置き換えて、そこに至る式を広範囲に配置して難読化したプログラム（以下、「難読化プログラム」という。）を生成するものである。
【００３４】
＜構成＞
図１は、本発明にかかるプログラム難読化装置のコンピューティングシステムの例である。
コンピューティングシステム１０は、汎用コンピュータ２０、プログラム等を表示するためのディスプレイ１１、キーボード等からユーザの指示を受け付けて処理を行う入力装置１２、及び、プログラム等を記憶する外部メモリ１３で構成される。コンピュータ２０は、入出力を管理するＩ／Ｏ部２１、演算を行うＣＰＵ（CentralProcessing Unit）２２及びメモリ２３を含み、通常のコンピュータの機能を有する。
【００３５】
本発明にかかるプログラム難読化を実行するための難読化プログラムは、メモリ２３や外部メモリ１３に記憶され、ＣＰＵ２２によって実行されることで、難読化の処理を実現する。対象プログラムは、外部メモリ１３から適時Ｉ／Ｏ部２１を介して読み込まれ、難読化が行われ、難読化プログラムは、Ｉ／Ｏ部２１を介して外部メモリ１３に書き出される。
【００３６】
以下、図２を用いて、本発明にかかるプログラム難読化装置１０００の構成を説明する。
図２は、プログラム難読化装置１０００の構成例を示すブロック図であり、プログラム難読化装置１０００は、変数追加部１１００、プログラム分割部１２００、写像情報生成部１３００、ブロック変換部１４００、および、秘密ブロック変換部１５００から構成される。また、装置外部から対象プログラム２０００を読み込む入力部（図示しない。）と、難読化プログラム３０００を出力する出力部（図示しない。）を備える。
【００３７】
対象プログラム２０００は、入力部によって読み込まれ、変数追加部１１００、プログラム分割部１２００、写像情報生成部１３００、ブロック変換部１４００、秘密ブロック変換部１５００によって順に処理され、難読化プログラム３０００が出力部によって出力される。
図３は、難読化の対象プログラム２０００の例を示す図であり、図４は、対象プログラムを難読化した後の難読化プログラム３０００の例を示す図である。
【００３８】
以下、各機能部について簡単に説明し、図３〜図１３を用い、具体例を交えて詳細に説明する。
まず、変数追加部１１００は、対象プログラム２０００に、対象プログラム２０００で使用されていない新たな変数（以下、「追加変数」と言う。）を追加する機能を有する。
次に、プログラム分割部１２００は、対象プログラムを１以上のプログラム命令からなる複数のブロックに分割する機能を有する。
【００３９】
写像情報生成部１３００は、追加変数をある値に対応させる写像を生成する機能を有し、コントロールフロー生成部１３１０、属性情報割当表生成部１３２０、及び、写像対応表生成部１３３０で構成される。
コントロールフロー生成部１３１０は、対象プログラムのコントロールフローを生成する機能を有し、属性情報割当表生成部１３２０は、コントロールフローを参照して、ブロックの入口と出口とに属性を割り当てて、属性情報割当表を生成する機能を有する。
【００４０】
また、写像対応表生成部１３３０は、属性情報割当表の属性ごとに写像を決定し、写像対応表を生成する機能を有する。
尚、属性情報割当表および写像対応表については、図９、図１２を用いて後で説明する。
ブロック変換部１４００は、写像情報生成部１３００で生成した写像に基づいて、各ブロックに追加変数の値を変換するプログラム命令を追加等する機能を有する。
【００４１】
秘密ブロック変換部１５００は、秘密情報を含むブロック（以下、「秘密ブロック」という。）に、追加変数を用いて秘密情報を算出するプログラム命令を追加等する機能を有する。
＜動作＞
図５は、プログラム難読化装置１０００の難読化処理を表すフローチャートである。本図を用いて、対象プログラム２０００から難読化プログラム３０００を生成する処理を説明する。その際、各機能部の詳細な機能も併せて説明する。尚、点線の矩形は、点線矩形内の処理を行う各機能部を示している。
【００４２】
対象プログラム２０００は、関数ｆｕｎｃを含み、関数ｆｕｎｃは変数ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃを入力として、プログラム命令群２０１０の処理を行い、変数ｐｍ＿ｂを出力する。また、プログラム命令２００１の「１２３」が秘密情報であるとする（図３参照）。
難読化プログラム３０００は、対象プログラム２０００に複数のプログラム命令が追加され、プログラム命令３００１では、秘密情報「１２３」が式「３＊ｐｍ＿０＋４＊ｐｍ＿１−４０」に変換されている（図４参照）。
【００４３】
以下、図５のフローチャートに沿って、難読化処理を説明する。
まず、対象プログラム２０００を入力部が、内部の作業メモリに読み込む（ステップＳ１１０）。
＜変数追加部１１００の処理＞
次に、変数追加部１１００が、読み込まれた対象プログラム２０００に変数を追加する（ステップＳ１２０）。
【００４４】
図６に、追加変数が追加された対象プログラム２１００を示す。
本実施形態では、「ｐｍ＿０」と「ｐｍ＿１」の２つの変数を追加するものとする。
変数追加部１１００は、追加変数「ｐｍ＿０」「ｐｍ＿１」の初期値をランダムに決定し、ここでは、それぞれ「０」「１」と決定し、追加変数「ｐｍ＿０」「ｐｍ＿１」の変数宣言を対象プログラム２０００に追加する。
【００４５】
変数宣言部２１１０が、このプログラムに追加された追加変数「ｐｍ＿０」「ｐｍ＿１」の変数宣言である。
なお、追加する変数の数、追加する変数の名前、変数の型は固定のものであっても、ユーザによって入力装置１２から入力されるものであっても、ランダムに決定したものであっても構わない。また、追加変数は配列とする構成であってもよい。
【００４６】
また、本実施形態では、変数宣言が必要なプログラミング言語であるＣ言語の場合について説明しているが、追加変数の定義方法等は、プログラム言語に応じたものとなる（以下、同様）。例えば、変数宣言を必要としないＢＡＳＩＣのような言語では、変数宣言を必要としないので、初期値の設定のみを記述すればよい。
＜プログラム分割部１２００の処理＞
変数追加部１１００は、追加変数を追加した対象プログラム２１００を、プログラム分割部１２００に渡し、プログラム分割部１２００は、対象プログラム２１００のうちのプログラム命令群２０１０を分割して、複数の基本ブロックを生成する（ステップＳ１３０）。
【００４７】
図７に、ブロック分割部１２００が対象プログラム２１００から生成した基本ブロックであるブロックＢ１〜ブロックＢ５を示す。
ここで、基本ブロックとは、１以上のプログラム命令からなるプログラム命令群であって、プログラム命令群の先頭以外では合流せず、プログラム命令群の最後以外では分岐しないプログラム命令群である。
【００４８】
より詳細には、基本ブロックを生成する場合、まず、次の３つのプログラム命令のいずれかをブロックの開始プログラム命令とする。１つ目は、プログラムの入口のプログラム命令（プログラムの一番最初に実行されるプログラム命令）、２つ目は、処理が合流するプログラム命令、例えば、Ｌａｂｅｌ文である。３つ目は、分岐となるプログラム命令、例えば、ｇｏｔｏ文の次のプログラム命令である。
【００４９】
次に、終了プログラム命令として、次の３つのプログラム命令のいずれかを決める。１つ目は、開始命令プログラムの次に処理が合流するプログラム命令の一つ前のプログラム命令、２つ目は、プログラムの出口の命令（プログラムの一番最後に実行される命令）、３つ目は、分岐となるプログラム命令である。
開始プログラム命令から終了プログラム命令までのプログラム命令からなるプログラム命令群を基本ブロックとする。
【００５０】
対象プログラム２１００を構成する全てのプログラム命令は、基本ブロック生成ステップにより、いずれかの一つの基本ブロックに含まれるように分割される（図７参照）。なお、これらの対象プログラムやブロックは、必要に応じて他の機能部から参照等することが可能であるものとする。
＜写像情報生成部１３００の処理＞
プログラム分割部１２００は、生成したブロックを、写像情報生成部１３００に渡し、写像情報生成部１３００は、各ブロックの入口と出口に設定する写像情報を生成する。これらの処理は、写像情報生成部１３００を構成するコントロールフロー生成部１３１０、属性情報割当表生成部１３２０および写像対応表生成部１３３０によって行われる。
【００５１】
ここで、各ブロックの入口と出口に設定する写像情報について説明する。
これら入口の写像情報（以下、「入口写像情報」という。）と出口の写像情報（以下、「出口写像情報」という。）は、ブロック変換部１４００や秘密ブロック変換部１５００で、ブロックを変換する際に使用される情報である。
写像情報は、ｐｍ＿Ｘ（Ｘ＝０、１）が取りうる値を要素とする集合を集合ＰＭ＿Ｘとし、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、ｐｍ＿０＿ａｆｔｅｒ∈ＰＭ＿０、ｐｍ＿１＿ａｆｔｅｒ∈ＰＭ＿１を満たす（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に対応させる写像であって、写像による像（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が１点（例えば、（０、１））となる写像を示す。
【００５２】
例えば、写像情報「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」は、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす全ての（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、（０、１）に対応させる写像を示す。これは、より具体的には、追加変数ｐｍ＿０、ｐｍ＿１の値を（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値である（０、１）にする変換を示す写像である。
【００５３】
＜コントロールフロー生成部１３１０の処理＞
ブロック分割部１２００は、対象プログラム２１００を分割して生成した基本ブロックを、写像情報生成部１３００を介してコントロールフロー生成部１３１０に渡し、コントロールフロー生成部１３１０は、コントロールフローを生成する（ステップＳ１４０）。
図８は、対象プログラム２１００のコントロールフローを示す図である。
【００５４】
コントロールフローはノードとエッジとからなるグラフであり、本図において、ノード１〜ノード５は、コントロールフローを構成するノードを示し、エッジ１〜エッジ６はコントロールフローを構成するエッジを示す。
コントロールフロー生成部１３１０は、対象プログラム２１００の基本ブロック（図７参照）から、図８に示すコントロールフローを以下の方法で生成する。
【００５５】
まず、コントロールフロー生成部１３１０は、対象プログラム２１００に含まれるブロックＢ１〜ブロックＢ５に対応するノード１〜ノード５を生成する。
次に、第一のブロックから第二のブロックに分岐がある場合、第一のブロックが対応するノードから第二のブロックが対応するノードへエッジを設ける。
例えば、ブロックＢ１では、プログラム命令「ｉｆ（ｐｍ＿ａ＞ｐｍ＿ｂ）ｇｏｔｏ  ｌａｂｅｌ  Ｃ；」における条件式「ｐｍ＿ａ＞ｐｍ＿ｂ」が偽の場合は（図７参照）、ブロックＢ２に分岐し、真の場合は、「ｌａｂｅｌ  Ｃ：」に対応するブロックＢ３に分岐する。
【００５６】
よって、ブロックＢ１に対応するノード１から、ブロックＢ２に対応するノード２へのエッジ１および、ブロックＢ３に対応するノード３へのエッジ２を設ける。
以下、同様にエッジ３〜エッジ６を設ける。
なお、本明細書では、分岐先が複数存在するものに限らず、ブロック間の移動が起こることを全て「分岐」と呼ぶものとする。
【００５７】
コントロールフローの生成については、「コンパイラの構成と最適化」（中田育夫、朝倉書店（１９９９年））のＰ２６８〜２７０に詳しい記載がある。
＜属性情報割当表生成部１３２０の処理＞
コントロールフローを生成したコントロールフロー生成部１３１０は、生成したコントロールフローを属性情報割当表生成部１３２０に渡し、属性情報割当表生成部１３２０は、渡されたコントロールフローを基に属性情報割当表１８００を生成する（ステップＳ１５０）。
【００５８】
属性情報割当表生成部１３２０は、コントロールフロー生成部１３１０が生成したブロックの入口と出口に属性を設定する。後で説明する写像対応表生成部１３３０が、この属性に対して写像情報を決定し、各ブロックの入口と出口に写像情報が設定されることになる。入口に設定される属性を入口属性、出口に設定される属性を出口属性というものとする。
【００５９】
このブロックの入口と出口に属性を設定する際、第一のブロックから第二のブロックに分岐がある場合には、第一のブロックの出口属性と第二のブロックの入口属性とは同じ写像情報とする。
例えば、図８に示すコントロールフローにおいて、ブロックＢ１に対応するノード１からブロックＢ２に対応するノード２にエッジ１に示される分岐があるので、ブロックＢ１の出口属性と、ブロックＢ２の入口属性には同じ属性を設定する。
【００６０】
すなわち、エッジの両端の入口と出口に同じ属性が割当てられることになるように、エッジに対して属性を割当てる。
また、繋がっているエッジのまとまりごとに１つの属性を割当てる。
例えば、ノード３の出口で繋がっているエッジ４とエッジ５、および、ノード３の入口でエッジ４と繋がっているエッジ２、ノード１の出口でエッジ２と繋がっているエッジ１とは、同じ属性を割当てる。
【００６１】
これらのエッジに同じ属性を割当てることで、エッジ１とエッジ２とエッジ４とエッジ５の両端の入口と出口とは、同じ属性となる。具体的には、ノード１の出口、ノード２に入口、ノード３の入口と出口、ノード４の入口は同じ属性となる。
図９は、属性情報割当表生成部１３２０が生成する属性情報割当表１８００の生成過程と、構成及び内容の例を示す図である。
【００６２】
属性情報割当表１８００は、ブロック１８１０、エッジ１８２０および属性１８３０とで構成される。
ブロック１８１０は、ブロックＢ１〜ブロックＢ５のそれぞれの入口と出口を示し、エッジ１８２０は、ブロックの入口と出口がそれぞれ接続しているエッジの番号を示す。例えば、「１」はエッジ１を表す。また、属性１８３０は、ブロックの入口と出口それぞれに設定された属性を示す。
【００６３】
この属性の決定方法を、図１０を用いて説明する。
図１０は、属性情報割当表生成処理を表すフローチャートである。
まず、属性情報割当表生成部１３２０は、コントロールフロー生成部１３１０が生成したブロック数の２倍の欄を持つテーブルを作成する（ステップＳ３１０）。
ここでは、コントロールフロー生成部１３１０が生成したブロック数が５であることより、１０個の欄からなるテーブルを作成する（図９参照）。
【００６４】
次に、属性情報割当表生成部１３２０は、属性１８３０に昇順に異なる数値を初期値として設定する。具体的には属性１８３０のブロック１８１０「ブロックＢ１入口」の欄から「ブロックＢ５出口」の欄に向かって、初期値「１」、「２」、・・・「１０」を設定する（ステップＳ３２０：図９の属性１８３０参照）。
初期値を設定した属性情報割当表生成部１３２０は、Ｓ３４０からＳ３６０を繰り返し実行する回数をカウントするためのカウンタｎに１を設定する（ステップＳ３３０）。
【００６５】
次に、出口のエッジ１８２０が「ｎ」のブロック、すなわち、エッジの始点となるブロックの出口の属性１８３０の値Ａと、入口のエッジ１８２０が「ｎ」のブロック、すなわち、エッジの終点となるブロックの入口の属性１８３０の値Ｂとを比較し、大きい方の値をＸ、小さい方の値をＹとし、写像情報割当表において値がＸである欄の値をＹに置換える（ステップＳ３４０）。
【００６６】
例えば、「ｎ＝＝１」の場合、すなわち、出口のエッジ１８２０が「１」のブロックはブロックＢ１、入口のエッジ１８２０が「１」のブロックはブロックＢ２である。これらの「ブロック１出口」と「ブロック２入口」の属性１８３０は、それぞれ「２」と「３」であり、小さい値である「２」で「３」を置き換える。すなわち、ブロックＢ２の入口の属性１８３０を「３」から「２」（属性１８０１参照）とする。
【００６７】
次に、ｎの値をインクリメントする（ステップＳ３５０）。
ｎの値がエッジの総数、本例では「６」より大きいかを判定し、大きい場合（ステップＳ３６０：ＹＥＳ）は全エッジに対する処理が終了しているため処理を終了し、小さい場合（ステップＳ３６０：ＮＯ）は次のエッジについて処理を続ける（ステップＳ３４０）。
【００６８】
続いて、「ｎ＝＝２」の場合、エッジ２の始点となるブロックＢ１の出口の属性の値「２」、終点となるブロックＢ３の入口の属性の値「５」を比較し、大きい方の値Ｘを「５」とし、小さい方の値Ｙを「２」とする。値「５」がある欄の値を「２」に置換え（属性１８０２参照）、１０個の欄の値を「１、２、２、４、２、６、７、８、９、１０」に更新する。
【００６９】
同様に、「ｎ＝＝３」の場合、エッジ３の始点となるブロック２の出口属性の値が「４」、終点となるブロックＢ５の入口属性の値が「９」であるので、値「９」がある欄の値を「４」に置換え（属性１８０３参照）、１０個の欄の値を「１、２、２、４、２、６、７、８、４、１０」に更新する。
同様に、「ｎ＝＝６」まで行い、ブロック４の出口属性の値「８」を、ブロックＢ５の入口属性の値「４」で置換え（属性１８０４参照）、１０個の欄の値を「１、２、２、４、２、２、２、４、４、１０」（属性１８３１参照）に更新する。
【００７０】
図１１は、各ブロックの入口と出口に設定された属性を示した、コントロールフローである。
＜写像対応表生成部１３３０の処理＞
属性情報割当表１８００を生成した属性情報割当表生成部１３２０は、生成した属性情報割当表を写像対応表生成部１３３０に渡し、写像対応表生成部１３３０は、渡された属性情報割当表の各属性に写像情報対応させる写像対応表１９００を生成する（ステップＳ１６０）。
【００７１】
写像対応表１９００は、属性情報割当表１８００中の属性に対応する写像情報を示している。従って、この写像対応表１９００を参照することにより、各ブロックに割り当てられた写像情報が得られることになる。
また、属性情報割当表１８００と写像対応表１９００は、図示しないメモリ上に生成されるものとする。
【００７２】
写像対応表生成部１３３０は、写像情報割当表１８００を構成する属性１８３１の属性数の写像情報を生成する。
図１２は、写像対応表１９００の構成および内容の例を示す図である。
属性１９５０は、写像情報割当表１８００の最終的な属性１８３１における属性の一覧である。また、写像対応表１９００は、ＩＤ１９１０と写像情報１９２０とで構成される。ＩＤ１９１０は、写像情報１９２０の識別子であり、属性１９５０と対応しているものとする（図１２：点線矢印参照）。
【００７３】
本実施例においては、写像情報割当表１８００の最終的な属性１８３１に属性が４種類、すなわち、「１」、「２」、「４」、「１０」であるので（図９参照）、４種類の写像情報を作成する。
以下、写像対応表生成部１３３０が写像情報１９２０を生成する手順を具体例を交えて説明する。
【００７４】
まず、コントロールフローの始点となるブロックの入口属性に対応する写像情報１９２０を、変数追加部１１００が追加した追加変数の初期値に基づいて設定する。
本実施形態では、始点となるブロックＢ１の入力属性は「１」であり（図１１参照）、追加変数「ｐｍ＿０」、「ｐｍ＿１」の初期値はそれぞれ「０」、「１」である。
従って、属性１９５０「１」に対応するＩＤ１９１０「Ｆ１」の写像情報１９２０（以下、「写像情報Ｆ１」等というものとする。）として、「ｐｍ＿０」、「ｐｍ＿１」の初期値を「ｐｍ＿０＿ａｆｔｅｒ」、「ｐｍ＿１＿ａｆｔｅｒ」とする写像情報を生成する。
【００７５】
すなわち、「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」を写像情報Ｆ１とする（図１２：ＩＤ１９１０「Ｆ１」参照）。
続いて、始点の入力属性以外の属性、「２」と「４」と「１０」に対する写像を、ランダムに生成する。
本実施形態では、属性「２」「４」「１０」に対応する写像情報として、ｐｍ＿Ｘ∈ＰＭ＿Ｘ（Ｘ＝０、１）を満たすランダムな値ｐｍ＿Ｘをｐｍ＿Ｘ＿ａｆｔｅｒの値とするような写像情報を生成する。
【００７６】
本実施形態では、属性「２」の写像情報Ｆ２を「ｐｍ＿０＿ａｆｔｅｒ＝３０；ｐｍ＿１＿ａｆｔｅｒ＝６；」と、属性「４」の写像情報Ｆ４を「ｐｍ＿０＿ａｆｔｅｒ＝１２；ｐｍ＿１＿ａｆｔｅｒ＝７；」と、属性「１０」の写像情報Ｆ１０を「ｐｍ＿０＿ａｆｔｅｒ＝１３；ｐｍ＿１＿ａｆｔｅｒ＝３１；」とする（図１２：写像対応表１９００参照）。
【００７７】
＜ブロック変換部１４００の処理＞
写像対応表１９００を生成した写像対応表生成部１３３０は、生成した写像対応表をブロック変換部１４００に渡し、ブロック変換部１４００は、渡された写像対応表に基づいて各ブロックにプログラム命令を追加し、変換後ブロックを生成する（ステップＳ１７０）。
【００７８】
全てのブロック、本実施形態ではブロックＢ１〜ブロックＢ５に、それぞれプログラム命令が追加されるまで（ステップＳ１８０）、ステップＳ１７０の処理を行う。
図１３は、ブロックＢ１〜ブロックＢ５を、ブロック変換部１４００が変換して生成した変換後ブロックを示す図である。プログラム命令群１４０１〜プログラム命令群１４０５は、それぞれのブロックに追加されたプログラム命令を表す。
【００７９】
ブロック変換部１４００は、もともとのブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する。
ここで、追加する機能は、追加変数の値が入口写像情報に示される値であった場合に、追加変数の値を出口写像情報に示される値に変換する機能である。具体的には、このような機能を実行するプログラム命令を追加する。
【００８０】
以下、追加する機能の具体例を説明した後、追加する機能を実現するためのプログラム命令の生成について説明する。
＜追加する機能＞
まず、ブロックＢ１に追加する機能を説明する。
ブロックＢ１に追加する機能は、写像情報Ｆ１を写像情報Ｆ２に変換するような機能であり（図１１参照）、この機能を実現するプログラム命令群を「Ｇ＿１＿２」というものとする。
【００８１】
ブロックＢ１の入口写像情報Ｆ１は「ｐｍ＿０＿ａｆｔｅｒ＝０；ｐｍ＿１＿ａｆｔｅｒ＝１；」であり、出口写像情報Ｆ２は、「ｐｍ＿０＿ａｆｔｅｒ＝３０；ｐｍ＿１＿ａｆｔｅｒ＝６；」である（図１２：写像対応表１９００参照）。
従って、ブロックＢ１に追加する機能は、（ｐｍ＿０、ｐｍ＿１）の値が入口写像情報Ｆ１における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値（０、１）である場合に、（ｐｍ＿０、ｐｍ＿１）の値を出口写像情報Ｆ２の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が示す（ｐｍ＿０、ｐｍ＿１）の値（３０、６）と等しくなるよう、（ｐｍ＿０、ｐｍ＿１）の値を変換する機能である。
【００８２】
具体的には、「ｐｍ＿０＝０」、「ｐｍ＿１＝１」であった場合に、「ｐｍ＿０＝３０」、「ｐｍ＿１＝６」となるような命令群であり、プログラム命令群Ｇ＿１＿２は「ｐｍ＿０＝ｐｍ＿０＊５＋ｐｍ＿１＊２０＋１０；  ｐｍ＿１＝ｐｍ＿１  ＊１３−７；」となる（図１３：プログラム命令群１４０１参照）。
なお、このような命令をどのように生成するかについては後述する。
【００８３】
プログラム命令群Ｇ＿１＿２、すなわち、プログラム命令群１４０１を追加することにより、（ｐｍ＿０、ｐｍ＿１）の値が入口写像情報Ｆ１における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値（０、１）である場合に、プログラム命令群１４０１「ｐｍ＿０＝０＊５＋１＊２０＋１０；ｐｍ＿１＝１＊１３−７；」が実行されることとなり、（ｐｍ０、ｐｍ１）＝（３０、６）となる。これは、出口写像情報Ｆ２の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）が示す（ｐｍ＿０、ｐｍ＿１）の値と等しい値である。
【００８４】
更に、他のブロック、ブロックＢ２〜ブロックＢ５に対しても同様の機能を持つプログラム命令群を追加する。
すなわち、プログラム命令群１４０２〜プログラム命令群１４０５も同様に、各ブロックの入口写像情報における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を代入すると、各ブロックの出口写像情報における（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）となるような処理を行うためのプログラム命令群である（図１３参照）。
【００８５】
＜追加する処理の生成＞
以下、上述したプログラム命令群Ｇ＿１＿２等をどのようにして生成するのかについての詳細を述べる。
入口写像情報としてＦ＿ＩＮを、出口写像情報としてＦ＿ＯＵＴを持つブロックに対する命令群Ｇ＿ＩＮ＿ＯＵＴを生成する場合の説明を行う。
【００８６】
例えば、Ｆ＿ＩＮとＦ＿ＯＵＴは、ブロックＢ１へ追加する命令群を生成する場合にはＦ１とＦ２であり、ブロックＢ２へ追加する命令群を生成する場合にはＦ＿２とＦ＿４である。
まず、ランダムに生成した定数をＲ１、Ｒ２、Ｒ３とし、式１、式２を、式１「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊Ｒ１−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ２」、式２「ｐｍ＿１＿ａｆｔｅｒ−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ３」
とする。
【００８７】
次に、（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に出口写像情報Ｆ＿ＯＵＴの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｏｆｏｒｅ）に入口写像情報Ｆ＿ＩＮの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値をそれぞれ代入し、式１、式２の値を計算し、それぞれの値をＶ１、Ｖ２とする。
【００８８】
計算したＶ１、Ｖ２を用いて、追加プログラム命令群Ｇ＿ＩＮ＿ＯＵＴを「ｐｍ＿０＝ｐｍ＿０＊Ｒ１＋ｐｍ＿１＊Ｒ２＋Ｖ１；ｐｍ＿１＝ｐｍ＿１＊Ｒ３＋Ｖ２」とする。
以下、具体的な一例として、Ｒ１、Ｒ２、Ｒ３をそれぞれ「５」「２０」「１３」としてブロックＢ１に追加する追加プログラム命令群Ｇ＿１＿２を生成する処理を説明する。
上述したＲ１、Ｒ２、Ｒ３の値を代入すると、式１、式２は、「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊５−ｐｍ＿１＿ｂｅｆｏｒｅ＊２０」「ｐｍ＿１＿ａｆｔｅｒ−ｐｍ＿１＿ｂｅｆｏｒｅ＊１３」となる。
【００８９】
上式の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）に出口写像情報Ｆ２の値（３０、６）を代入し、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）に入口写像情報Ｆ１の値（０、１）を代入すると、それぞれ「３０−０＊５−１＊２０」「６−１＊１３」となる。すなわち、Ｖ１、Ｖ２はそれぞれ「１０」「−７」となる。
よって、プログラム命令群Ｇ＿１＿２は「ｐｍ０＝ｐｍ０＊５＋ｐｍ１＊２０＋１０：ｐｍ＿１＝ｐｍ＿１＊１３−７；」となる。このようにして生成した追加プログラム命令群Ｇ＿１＿２をブロックＢ１の先頭に追加し、変換後ブロックとする（図１３：プログラム命令群１４０１参照）。
【００９０】
＜秘密ブロック変換部１５００の処理＞
変換後ブロックを生成したブロック変換部１４００は、生成した変換後ブロックを秘密ブロック変換部１５００に渡し、秘密ブロック変換部１５００は、渡された変換後ブロックから秘密情報を含む秘密ブロックを特定し（ステップＳ１９０）、秘密情報を追加変数を用いて算出する式に置き換えて、難読化プログラムを生成する（ステップＳ２００）。
【００９１】
ここで、秘密ブロックの特定の方法は、対象プログラム２０００から秘密情報を検出し、その秘密情報が含まれるブロックを秘密ブロックとして特定する。
秘密情報を検出する方法としては、予め、秘密情報を特定のコードで囲んでおいたり、難読化開始前にユーザが指定する等して、秘密ブロック変換部１５００が認識できるようにしておく。また、秘密ブロックの中に秘密情報は複数あってもよく、また、対象プログラム中に秘密ブロックが複数あってもよい。
【００９２】
次に、秘密ブロック変換部１５００は、プログラムに含まれる秘密情報を、変数追加部１１００で追加した追加変数を用いて算出する処理に変更する。
このようにして生成した変換後の秘密ブロックを含む難読化後プログラム３０００を、図１４に示す。
以下、秘密情報を追加変数を用いて算出するプログラム命令の求め方を説明する。
【００９３】
まず、ランダムに生成した定数をＲ４、Ｒ５とし、以下の式３を生成する。
式３「ｐｍ＿０＿ａｆｔｅｒ−ｐｍ＿０＿ｂｅｆｏｒｅ＊Ｒ４−ｐｍ＿１＿ｂｅｆｏｒｅ＊Ｒ５」。
次に、「ｐｍ＿０＿ａｆｔｅｒ」に秘密情報の値を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）に秘密ブロックの出口写像情報Ｆ＿ＯＵＴの（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）の値を代入して式３の値を計算し、計算した値をＶ３とする。
【００９４】
ここでは、秘密ブロックであるブロックＢ５（図１３参照）に含まれる秘密情報の値「１２３」の変換を例にとり説明する。
秘密情報「１２３」を含むブロックはブロックＢ５であり、ブロックＢ５の出口写像情報Ｆ１０の（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）は（１３、３１）である。
Ｒ４、Ｒ５をそれぞれ「３」、「４」とし、これらを式３に代入し、「１２３−１３＊３−３１＊４」よりＶ３の値「−４０」を求める。
【００９５】
次に、秘密情報の値を「（ｐｍ＿０＊Ｒ３＋ｐｍ＿１＊Ｒ４＋Ｖ３）」に置き換える。すなわち、プログラム命令「ｂ＝ｂ＊１２３；」を「ｂ＝ｂ＊（３＊ｐｍ＿０＋４＊ｐｍ＿１−４０）；」に置き換える（図１４：プログラム命令１５０１参照）。
ここで、最終的に得られる上式は、ブロックＢ５における入力写像情報（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）の値にランダムな数Ｒ３、Ｒ４をかけて加算した演算結果と秘密情報「１２３」との差分Ｖ３を算出し、加算する式となっている。
【００９６】
これにより上式の計算結果は、入口属性が属性情報割当表１８００の属性１８３１に示される値「４」（図９参照）である場合には、常に秘密情報「１２３」が得られる。
難読化後プログラム３０００は、秘密ブロック変換部１５００により生成された秘密情報変換後のブロックＢ５と、ブロック変換部１４００により生成された変換後ブロックＢ１〜ブロックＢ４とを備えるプログラムである。
【００９７】
難読化プログラム３０００は、出力部により外部メモリ１３に出力される（ステップＳ２１０）。
＜実施形態１の効果＞
実施形態１では、秘密情報を、複数のプログラム命令を実行することによって算出されるように変換する難読化の一例を示した。この難読化方法は以下の３点を特徴とする。
【００９８】
（イ）コントロールフローの始点となるブロック、例えばブロックＢ１、の入口属性Ｆ＿ＩＮを、追加変数の初期値とする（写像対応表生成部１３３０の処理参照）。
（ロ）各ブロックに、追加変数がそのブロックの入口写像情報Ｆ＿ＩＮで示す値であった場合に、そのブロックの出口写像情報Ｆ＿ＯＵＴに示す値に変換する機能が追加される（ブロック変換部１４００の処理参照）。
【００９９】
（ハ）複数の分岐元を持つノードの全ての分岐元のノードに対応するブロックの出口写像情報は、分岐先のノードに対応するブロックの入口写像情報と等しい（属性情報割当表１８００参照）。例えば、ブロックＢ５のように２つの分岐元ブロックＢ２とブロックＢ４とを持つ場合、ブロックＢ２とブロックＢ４のブロックＢ５に対する出口写像情報は、ブロックＢ５の入口写像情報と等しい（図１１参照）。
【０１００】
以上、３点の特徴により、正常系の実行時において、難読化後プログラムがどのような実行ルートで実行されたとしても、追加変数の値はその秘密ブロックに対して（ロ）で設定した入口写像情報に示される値となる。
よって、秘密情報を含むブロックＢ５の入口写像情報に基づき算出される秘密情報の値は、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されたとしても、正しい値「１２３」となる。
【０１０１】
本実施形態の難読化プログラムでは、追加変数の値を算出するプログラム命令が全てのブロックに追加されている。また、秘密情報は、追加変数を用いて算出される。よって、不正解析者が、追加されたプログラム命令を見つけ出して秘密情報の値を解析しようとした場合、追加されたプログラム命令がプログラムの様々な位置にあるので、追加されたプログラム命令すべてを見つけ出すことが困難になる。従って、秘密情報に至るまでに長時間を要し、結果として秘密情報が守られる事となる。
＜実施形態２＞
＜概要＞
実施形態１が、新たな変数を追加し、この追加変数の値を算出するプログラム命令を全てのブロックに追加し、更に、秘密情報をかかる追加変数から算出する式に置き換えて難読化プログラムを生成するものであったのに対し、本実施形態では、対象プログラムに既に存在する変数を利用し、その変数の役割をプログラムの途中で置換えて難読化プログラムを生成するものである。
【０１０２】
ここでは、実施形態１との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表４９００を図１５に示す。
写像対応表４９００は、ＩＤ１９１０と写像情報４９２０とで構成され、ＩＤ１９１０は実施形態１と同様に、写像情報４９２０の識別子である。また、変数の置換え関係４９３０は、写像対応表４９００を構成しないが、説明の便宜上、変数の置換え関係を矢印を用いて表したものである。
【０１０３】
すなわち、実施形態１の写像対応表１９００（図１２参照）では、属性に応じて、変数の値がある値に決まったが、本実施形態では、属性に応じて、変数の値がどの変数の値となっているかが決まることになる。
＜構成＞
図１６は、実施形態２にかかるプログラム難読化装置４０００の構成例を示すブロック図である。
【０１０４】
実施形態１のプログラム難読化装置１０００の構成（図２参照）と異なる点は、４点ある。
１点目は、変数追加部１１００が無い点であり、２点目は、写像情報生成部４４００の写像対応表生成部４３３０が生成する写像の内容が異なる点である。３点目は、写像の内容が異なることによるブロック変換部４４００で追加するプログラム命令群の生成方法が異なる点である。また、４点目は、追加変数が追加されていないため、秘密ブロック変換部４５００での秘密情報の算出方法が異なる点である。
【０１０５】
＜動作＞
以下、写像情報生成部４４００の写像対応表生成部４３３０、ブロック変換部４４００、秘密ブロック変換部４５００の処理について説明する。他の動作は、実施形態１と同様である（図５等参照）。
＜写像情報生成部４４００の写像対応表生成部４３３０の処理＞
写像情報生成部４４００は、プログラム分割部１２００で生成した各ブロックの入口と出口に設定する写像情報を生成する。
【０１０６】
本実施形態で設定する写像情報について、簡単に説明する。
写像情報は、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）が取りうる値を要素とする集合を集合ＰＭ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）とし、ｐｍ＿ａ＿ｂｅｆｏｒｅ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）をｐｍ＿ａ＿ａｆｔｅｒ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ａｆｔｅｒ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ａｆｔｅｒ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、  ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像であって、変数の役割を置換える写像を示す。
【０１０７】
具体的には、例えば写像情報「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の値がそれぞれ（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）であった場合に、それぞれの値を変数（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に代入する写像を示している。すなわち、上述の写像情報は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割をそれぞれ（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に置換える置換えを示した写像を示している。
【０１０８】
＜写像対応表生成部４３３０の処理＞
写像対応表生成部４３３０は、実施形態１と同様、属性情報割当表１８００の属性に対応する写像情報を示す写像対応表４９００を生成する。
なお、本実施形態において、属性情報割当表は実施形態１の属性情報割当表１８００と同じである（図９参照）。
【０１０９】
写像対応表生成部４３３０は、属性情報割当表１８００を構成する属性の種類数、すなわち、４種類の写像情報を生成する。
各写像情報の作成は、例えば以下のようにして行う。
ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅからランダムに選んだ１つをｐｍ＿ａ＿ａｆｔｅｒに対応させ、残りの二つからランダムに選んだ１つをｐｍ＿ｂ＿ａｆｔｅｒに対応させ、さらに残りの１つをｐｍ＿ｃ＿ａｆｔｅｒに対応させる。
【０１１０】
例えば、「ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ、」を順に選んだ場合、写像情報は、「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」となる。
本実施形態では、図１１のコントロールフローの始点となるブロックＢ１の入口写像情報の属性「１」に対応する写像情報Ｆ１を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」とする。
【０１１１】
また、順次、他の属性「２」「４」「１０」に対応する写像情報を決め、写像対応表４９００を完成させる。
＜ブロック変換部４４００の処理＞
ブロック変換部４４００は、もともとのブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する手段である。追加する機能は、入口写像情報に示される変数の置換えが行われている場合に、出口写像情報を示す変数の置換えを行う機能である。また、この置換えは、もとからあるプログラム命令で使用されている変数を用いて行う。
【０１１２】
以下、追加する機能および変数の置換えを説明した後、追加する機能を実現するための処理の生成について説明する。
＜追加する機能＞
ブロックに追加する機能を、具体例を用いて説明する。
図１７は、図７のブロックＢ２をブロック変換部４４００によって変換して生成した変換後ブロックＢ２を示す図である。
【０１１３】
白抜き矢印の左側に変換前のブロックＢ２（以下、「変換前ブロックＢ２」という。）を、右側に変換後のブロックＢ２（以下、「変換後ブロックＢ２」という。）を示している。
変換後ブロックＢ２は、変換前ブロックＢ２に、変数の役割を置換えるプログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ：ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｔｍｐ；」（図１７：プログラム命令群４４０１参照）を追加し、さらに、変換前ブロックＢ２に含まれる変数を出口写像情報Ｆ４に基づいて置き換えて（プログラム命令群４４０２参照）生成したブロックである。
【０１１４】
プログラム命令群Ｇ＿２＿４は、変数の役割を置換えるためのプログラム命令群であり、ブロックＢ２が正常系で実行される際に、このブロックＢ２が実行される前までに入口写像情報に基づき変数の役割が置換えられていた場合に、出口写像情報に基づく変数の置換えを行うプログラム命令群である。
以下、プログラム命令群４４０２で示されるプログラム命令群Ｇ＿２＿４が、上記の特徴を持つプログラム命令群であることを説明する。
【０１１５】
まず、ブロックＢ２の入口写像情報は図１１に示すようにＦ２であり、出口写像情報はＦ４である。
図１８は、ブロックＢ２の入口と出口での変換を示した図である。なお、Ｆ２＿ＩＮＶは、Ｆ２の逆写像をあらわすものとする（変換４４２０）。
入口写像情報Ｆ２は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に置換える置換え（変換４４１０）であって、出口写像情報Ｆ４は変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ｂ、ｐｍ＿ａ、ｐｍ＿ｃ）に置換える置換え（変換４４３０）である（図１５：写像対応表４９００参照）。
【０１１６】
また、プログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ：ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｐｍ＿ａ；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割を（ｐｍ＿ｂ、ｐｍ＿ｃ、ｐｍ＿ａ）に置換える処理である。
この時、入口写像情報Ｆ２による置換えと、プログラム命令群Ｇ＿２＿４による置換えの両方を行った際の置換えを図１９の下段に示す。
【０１１７】
図１９に示すように、入口写像情報Ｆ２の置換え（変換４４１０）を行った後、さらにプログラム命令群Ｇ＿２＿４による置換え（変換４４９０）を行った場合、もともとの（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）を（ｐｍ＿ｂ、ｐｍ＿ａ、ｐｍ＿ｃ）に置換えた置換えと等しくなる。これは出口写像情報Ｆ４の示す置換えと等しい。
なお、プログラム命令群Ｇ＿２＿４の生成方法については、後述する。
【０１１８】
＜変数の置換え＞
さらに、ブロックＢ２では、ブロックに含まれる変数を出口写像情報Ｆ４に基づき書き換える必要がある。
具体的には、ブロックＢ２における「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」におけるｐｍ＿ｂを出口写像情報Ｆ＿４に基づいてｐｍ＿ａに置換えて「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」とする（図１７：プログラム命令４４０２）。
【０１１９】
＜追加する処理の生成＞
以下、上述したプログラム命令群Ｇ＿２＿４等をどのようにして生成するのかについて詳細を述べる。
変換を行うブロックの入力写像情報をＦ＿ＩＮ、出口写像情報をＦ＿ＯＵＴとし、入力写像情報Ｆ＿ＩＮによる置換えの逆変換をＦ＿ＩＮ＿ＩＮＶとする。
【０１２０】
例えば、変換を行うブロックがブロックＢ２のとき、Ｆ＿ＩＮは、Ｆ２であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に対応させる写像である（図１８：変換４４１０参照）。
この時、Ｆ２＿ＩＮＶは、Ｆ＿２のｐｍ＿Ｘ＿ａｆｔｅｒとｐｍ＿Ｘ＿ｂｅｆｏｒｅとを置換えた写像であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ）に対応させる写像となる（図１８：変換４４２０参照）。
【０１２１】
次に、Ｆ＿ＩＮ＿ＩＮＶとＦ＿ＯＵＴの合成による置換えを求める。
例えば、対象ブロックがブロックＢ２である場合、Ｆ＿ＯＵＴはＦ４であり、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像となる（図１８：変換４４３０参照）。
【０１２２】
この時、Ｆ＿Ｉ＿ＩＮＶとＦ＿ＯＵＴの合成による置換えは、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ、ｐｍ＿ａ＿ａｆｔｅｒ）に対応させる写像となる（図１９：変換４４９０）。
次に、上記の置換えを行う追加プログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ；ｐｍ＿ａ＝ｐｍ＿ｃ；ｐｍ＿ｃ＝ｐｍ＿ｂ；ｐｍ＿ｂ＝ｔｍｐ；」を生成し、ブロックＢ２に追加する。
【０１２３】
その後、出口写像情報Ｆ＿ＯＵＴの示す置換えに基づき、ブロックＢ２に含まれる変数を置換える。
具体的には、ブロックＢ２に対応する出口写像情報Ｆ４が「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ；」を含むことから、変数ｐｍ＿ｂはｐｍ＿ａに置換えられたことが分かるので、ブロックＢ２のｐｍ＿ｂをｐｍ＿ａに置き換える。すなわち、式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」に置換える。
【０１２４】
このようにして生成したブロックが変換後ブロックＢ２となる。他のブロックＢ１、ブロックＢ３〜ブロックＢ５についても同様に変換を行う。
このような変換を行うことにより、各ブロックは常に、一つ前のブロックの出口写像情報に対応する変換を打ち消した後、自身の出口写像情報に対応する変換を行う。
これにより、正常系の実行時には、各ブロックでどのように分岐やループが発生したとしても、各ブロックにおける変数の置換えの状態は、図１５に示される写像情報４９２０が示すものと等しくなる。
【０１２５】
また、出口写像情報に基づいて変換前のブロックに含まれる変数を置換えるので、各ブロックの演算結果が変換前のブロックと等しくなることが保証できる。
＜秘密ブロック変換部４５００の処理＞
実施形態１では、秘密情報は追加変数を用いた式で求めたが、本実施形態では追加変数は追加されない。従って、本実施形態では、秘密情報の変更しないものとするが、変換した変数を用いたり、他の変数を用いて難読化することとしてももちろんよい。
【０１２６】
＜実施形態２の効果＞
実施形態２では、変数の役割をプログラムの途中で置換える難読化の一例を示した。この難読化方法は以下の４点を特徴とする。
（イ）コントロールフローの始点となるノード２に対応するブロックＢ２の入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てている（写像対応表生成部４３３０の処理参照）。
【０１２７】
（ロ）各ブロックに、変数の置換えが入口写像情報Ｆ＿ＩＮで示す置換えであった場合に、出口写像情報Ｆ＿ＯＵＴに示す変数の置換えを行う機能が追加される（ブロック変換部４４００の処理参照）。
（ハ）ノード５のような複数の分岐元（ノード２、ノード４）を持つノードに対応する全ての分岐元のブロックの出口写像情報は、分岐先のノード（ノード５）に対応するブロックの入口写像情報と等しい（属性情報割当表１８００参照）。
【０１２８】
（ニ）各ブロックの変数は出口写像情報に基づき置換えられている。
以上、４点の特徴により、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されても、各ブロックに実行制御が遷移した際、変数は、そのブロックの入口写像情報に示す置換えが成された変数となる。
このような難読化により、プログラムの様々な位置で変数の役割が置換わり、プログラムの解析を困難にすることができる。また、ブロック毎に、変数の役割が替わることにより、あるブロックでの変数が、他のブロックでどの変数になっているかが解り難くなるので、解析を困難にすることができる。
＜実施形態３＞
＜概要＞
実施形態２が、対象プログラムに既に存在する変数を利用し、その変数の役割をプログラムの途中で置換えて難読化プログラムを生成するものであったのに対し、本実施形態では、変数の値に所定の演算を施した値を、その変数に保持させることで難読化プログラムを生成するものである。例えば、変数ｐｍ＿ａに１４を足した値を、変数ｐｍ＿ａに保持させるなどである。
【０１２９】
ここでは、実施形態２との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表５９００を図２０に示す。
写像対応表５９００は、ＩＤ１９１０と写像情報５９２０とで構成され、ＩＤ１９１０は実施形態２と同様に、写像情報５９２０の識別子である。
【０１３０】
すなわち、実施形態２の写像対応表４９００（図１５参照）では、属性に応じて、変数の値がどの変数の値となっているかが決まったが、本実施形態では、属性に応じて、変数の値が、どの様な演算が施された値であるかが決まることになる。
＜構成＞
図２１は、実施形態３にかかるプログラム難読化装置５０００の構成例を示すブロック図である。
【０１３１】
実施形態２のプログラム難読化装置４０００の構成（図１６参照）と異なる点は、以下の２点である。
１点目は、写像情報生成部５４００の写像対応表生成部５３３０が生成する写像の内容が異なる点である。２点目は、写像の内容が異なることによるブロック変換部５４００で追加するプログラム命令群の生成方法が異なる点である。
【０１３２】
＜動作＞
以下、写像情報生成部５４００の写像対応表生成部５３３０、ブロック変換部５４００の各処理について説明する。他の動作は、実施形態１および実施形態２と同様である（図５、図１６等参照）。
＜写像情報生成部５４００の写像対応表生成部５３３０の処理＞
まず、本実施形態で設定する写像情報について説明する。
【０１３３】
実施形態３の写像情報は、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）が取りうる値を要素とする集合を集合ＰＭ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）とし、ｐｍ＿ａ＿ｂｅｆｏｒｅ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ∈ＰＭ＿Ｂを満たす（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）をｐｍ＿ａ＿ａｆｔｅｒ∈ＰＭ＿Ａ、ｐｍ＿ｂ＿ａｆｔｅｒ∈ＰＭ＿Ｂ、ｐｍ＿ｃ＿ａｆｔｅｒ∈ＰＭ＿Ｃを満たす（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）に対応させる写像であって、変数ｐｍ＿Ｘ＿ｂｅｆｏｒｅにある数を加減算したものをｐｍ＿Ｘ＿ａｆｔｅｒに対応させる写像を示す。
【０１３４】
例えば、写像情報「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒ＋１４；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋１２；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ−６；」は、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の値がそれぞれ（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）であった場合に、（ｐｍ＿ａ＿ｂｅｆｏｒｅ＋１４、ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋１２、ｐｍ＿ｂ＿ｂｅｆｏｒｅ−６）値をそれぞれ変数（ｐｍ＿ａ、ｐｍ＿ｃ、ｐｍ＿ｂ）に代入する写像を示している。
【０１３５】
すなわち、変数（ｐｍ＿ａ、ｐｍ＿ｂ、ｐｍ＿ｃ）の役割をそれぞれ（ｐｍ＿ａ＋１４、ｐｍ＿ｃ＋１２、ｐｍ＿ｂ−６）に置換える置換えを示す。
＜写像情報生成部５３００の写像対応表生成部５３３０の処理＞
写像対応表生成部５３３０は、実施形態２と同様、属性情報割当表１８００の属性に対応する写像情報を示す写像対応表５９００を生成する。
【０１３６】
なお、本実施形態において、属性情報割当表は実施形態１の属性情報割当表１８００と同じである（図９参照）。
写像対応表生成部５３３０は、属性情報割当表１８００を構成する属性の種類数、すなわち、４種類の写像情報を生成する。
各写像情報の作成は例えば以下のようにして行う。
【０１３７】
Ｒ１∈ＰＭ＿Ａ、Ｒ２∈ＰＭ＿Ｂ、Ｒ３∈ＲＭ＿Ｃを満たすＲ１、Ｒ２、Ｒ３をランダムに生成し、「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋Ｒ１；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋Ｒ２；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋Ｒ３；」を写像情報とする。
具体的には、図１１のコントロールフローの始点となるブロックの入口写像情報の属性「１」に対応する写像情報Ｆ１を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」とする。
【０１３８】
次に、その他の識別子「２」「４」「１０」に対応する写像情報を決める。
＜ブロック変換部５４００の処理＞
ブロック変換部５４００は、変換前ブロックが保持する機能に、機能追加を行ったブロックを変換後ブロックとして生成する。ここで、追加する機能は、入口写像情報に示される変数の置換えが行われている場合に、出口写像情報を示す変数の置換えを行う機能である。
【０１３９】
以下、追加する機能、追加する機能を実現するための処理の生成、および、変数の置換えについて説明する。
＜追加する機能＞
以下、ブロックに追加する機能を、具体例を用いて説明する。
図２２は、ブロックＢ２を、ブロック変換手段５４００によって変換して生成した変換後ブロックＢ２を示す図である。
【０１４０】
白抜き矢印の左側に変換前ブロックＢ２を、右側に変換後ブロックＢ２を示している。
具体的には、変換前ブロックＢ２の先頭に、プログラム命令群Ｇ＿２＿ＩＮＶ（図２２：プログラム命令群５４０１参照）を追加し、その後にプログラム命令群Ｇ＿４（図２２：プログラム命令群５４０２参照）を追加する。
さらに、ブロックに含まれる変数をブロックの出口写像情報に基づいて変換する（図２２：プログラム命令５４０３参照）。
【０１４１】
プログラム命令群Ｇ＿２＿ＩＮＶは、「ｐｍ＿ａ＝ｐｍ＿ａ−１４；  ｐｍ＿ｂ＝ｐｍ＿ｂ−１２；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋６；」であり、プログラム命令群Ｇ＿４は、「ｐｍ＿ａ＝ｐｍ＿ａ＋７；  ｐｍ＿ｂ＝ｐｍ＿ｂ＋５；  ｐｍ＿ｃ  ＝ｐｍ＿ｃ＋２１；」である。
以下、プログラム命令群Ｇ＿２＿ＩＮＶ、プログラム命令群Ｇ＿４の生成、および、ブロックに含まれる変数の置換えの詳細を説明する。
【０１４２】
＜プログラム命令群Ｇ＿２＿ＩＮＶの生成＞
プログラム命令群Ｇ＿２＿ＩＮＶは、ブロックＢ２の入口写像情報Ｆ２の逆写像を行う追加プログラム命令群である。
プログラム命令群Ｇ＿２＿ＩＮＶの生成の仕方を説明する。
まず、写像情報Ｆ２より、（ｐｍ＿ａ＿ｂｅｆｏｒｅ、ｐｍ＿ｂ＿ｂｅｆｏｒｅ、ｐｍ＿ｃ＿ｂｅｆｏｒｅ）を（ｐｍ＿ａ＿ａｆｔｅｒ、ｐｍ＿ｂ＿ａｆｔｅｒ、ｐｍ＿ｃ＿ａｆｔｅｒ）を用いて求める式を生成する。
【０１４３】
これは、「ｐｍ＿ａ＿ｂｅｆｏｒｅ＝ｐｍ＿ａ＿ａｆｔｅｒ−１４；  ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−１２；  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＝ｐｍ＿ｃ＿ａｆｔｅｒ＋６；」となる。
この式の、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換え、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘに置換えた「ｐｍ＿ａ＝ｐｍ＿ａ−１４；  ｐｍ＿ｂ＝ｐｍ＿ｂ−１２；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋６；」をプログラム命令群Ｇ＿２＿ＩＮＶとする。
【０１４４】
＜プログラム命令群Ｇ＿４の生成＞
プログラム命令群Ｇ＿４は、ブロックＢ２の出口写像情報Ｆ４の写像を行う追加プログラム命令群である。
プログラム命令群Ｇ＿４の生成を説明する。
写像情報Ｆ４「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋７；  ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；  ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ＋２１；」の、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換え、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘに置換える。
【０１４５】
置換えによってできた「ｐｍ＿ａ＝ｐｍ＿ａ＋７；  ｐｍ＿ｂ＝ｐｍ＿ｂ＋５；  ｐｍ＿ｃ＝ｐｍ＿ｃ＋２１；」をプログラム命令群Ｇ＿４とする。
＜変数の置換え＞
ブロックＢ２に含まれる変数の置換えを説明する。
変数の置換えは、代入式の左辺に変数（代入によって値が決まる変数）がある場合と、右辺に変数（代入の値を決める）がある場合とで異なった変換方法によって行う。なお、右辺と左辺の両方に変数がある場合には、右辺に変数がある場合の変換と、左辺に変数がある場合の変換の両方を施す。
【０１４６】
ここで、左辺と右辺の具体例を示すと、ブロックＢ２における「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」においては、左辺とは「ｐｍ＿ｂ」であり、右辺は「ｐｍ＿ｂ＊８；」である。
以下、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を置換え対象プログラム命令とし、左辺の変数の置換えと右辺の変数の置換えとを説明する。
＜左辺の変数がある場合の置換え＞
プログラム命令の左辺に変数が含まれている場合には、その変数に対する置き換えを行う。このような変換を行うのは、各プログラム命令の演算結果に出口写像情報を反映させる必要があるからである。
【０１４７】
左辺の変数ｐｍ＿Ｘを置換える場合、そのブロックの出口写像情報Ｆ＿ＯＵＴにおいて、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式を全て見つける。
ここで、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が見つからなかった場合、そのプログラム命令に対しては変換の必要がないため、何も変換を行わない。
本具体例では、式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」の左辺の変数が「ｐｍ＿ｂ」であり、ブロックＢ２の出口写像情報がＦ４であることから、ｐｍ＿ｂ＿ｂｅｆｏｒｅを含む式「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；」が見つかることとなる。
【０１４８】
次に、見つけた式のｐｍ＿Ｘ＿ｂｅｆｏｒｅを置換え対象プログラム命令の右辺の内容に置換える。ここでは、ｐｍ＿ｂ＿ｂｅｆｏｒｅを「（ｐｍ＿ｂ＊８）」に置換え、「ｐｍ＿ｂ＿ａｆｔｅｒ＝（ｐｍ＿ｂ＊８）＋５；」とする。
その後、「ｐｍ＿ｂ＿ａｆｔｅｒ」を変数「ｐｍ＿ｂ」に変換することにより、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」という式が得られる。
【０１４９】
この式は、もともとの式の演算結果に対して、出口写像「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５；」を反映させた式である。すなわち、もともとの式「ｐｍ＿ｂ＊８」に対して、出口写像情報の影響である「＋５」を加えた式になる。
なお、上述の例において、左辺の変数がｐｍ＿Ｘ（Ｘ＝ａ，ｂ，ｃ）であって、写像情報にｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が複数ある場合には、対象プログラム命令を、それら複数の式からなるプログラム命令に置換え、次に、それぞれの式のｐｍ＿Ｘ＿ｂｅｆｏｒｅを置換え対象プログラム命令の右辺の内容に置換える。
【０１５０】
以上が、左辺に変数がある場合の置換えである。
＜右辺の変数がある場合の置き換え＞
プログラム命令の右辺に変数が含まれている場合には、その変数に対する置き換えを行う。
このような変換を行うのは、プログラム命令の右辺に含まれている変数は入口写像による変換が行われた状態の変数であるので、もともとの式で演算を行っても適切な計算結果が得られないためである。すなわち、プログラム命令の右辺に含まれている変数から入力写像の影響を消すことにより、適切な結果が得られるような式に修正する。
【０１５１】
以下の例では説明では、上述した左辺に変数がある場合の置き換えにおいて生成された「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」の右辺の変数を置換える例を示す。
まず、ブロックＢ２の出口写像情報Ｆ４の逆写像Ｆ４＿ＩＮＶを上述した方法で生成する。
ここでは、Ｆ４＿ＩＮＶは、「ｐｍ＿ａ＿ｂｅｆｏｒｅ＝ｐｍ＿ａ＿ａｆｔｅｒ−７；  ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−５；  ｐｍ＿ｃ＿ｂｅｆｏｒｅ＝ｐｍ＿ｃ＿ａｆｔｅｒ−２１」となる。
【０１５２】
次に、プログラム命令中の、右辺の変数ｐｍ＿Ｘをｐｍ＿Ｘ＿ｂｅｆｏｒｅに置換える。すなわち、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＊８）＋５；」を「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」に置き換える。
次に、Ｆ４＿ＩＮＶ中から、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式を見つける。ここで、Ｆ４＿ＩＮＶ中から、ｐｍ＿Ｘ＿ｂｅｆｏｒｅを含む式が見つからなかった場合は、変数ｐｍ＿Ｘに対応する入口写像情報がない、すなわち、変数ｐｍ＿Ｘは特に変換されていない状態であるので、置き換えた式中のｐｍ＿Ｘ＿ｂｅｆｏｒｅを変数ｐｍ＿Ｘに戻して処理を終了する。
【０１５３】
ここでは、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」の右辺に「ｐｍ＿ｂ＿ｂｅｆｏｒｅ」が含まれているため、これに対応する「ｐｍ＿ｂ＿ｂｅｆｏｒｅ＝ｐｍ＿ｂ＿ａｆｔｅｒ−５；」が見つかる。
続いて、見つかった式に基づき、ｐｍ＿Ｘ＿ｂｅｆｏｒｅをｐｍ＿Ｘ＿ａｆｔｅｒを使った式に置換える。すなわち、「ｐｍ＿ｂ＝（ｐｍ＿ｂ＿ｂｅｆｏｒｅ＊８）＋５；」を「ｐｍ＿ｂ＝（（ｐｍ＿ｂ＿ａｆｔｅｒ−５）＊８）＋５；」に置き換える。
【０１５４】
最後に、ｐｍ＿Ｘ＿ａｆｔｅｒをｐｍ＿Ｘに置換える。すなわち「ｐｍ＿ｂ＝（（ｐｍ＿ｂ＿ａｆｔｅｒ−５）＊８）＋５；」を「ｐｍ＿ｂ＝（（ｐｍ＿ｂ−５）＊８）＋５；」に置き換える。
なお、右辺にｐｍ＿ｂ＿ｂｅｆｏｒｅを含むプログラム命令が複数ある場合には、それぞれのｐｍ＿ｂ＿ｂｅｆｏｒｅを（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。
【０１５５】
また、一つのプログラム命令に、ｐｍ＿ａ＿ｂｅｆｏｒｅとｐｍ＿ｂ＿ｂｅｆｏｒｅが含まれる場合は、ｐｍ＿ａ＿ｂｅｆｏｒｅを（ｐｍ＿ａ＿ａｆｔｅｒ−７）に、ｐｍ＿ｂ＿ｂｅｆｏｒｅを（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。例えば、ｐｍ＿ｂ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＊ｐｍ＿ｂ＿ｂｅｆｏｒｅは、ｐｍ＿ｂ＝（ｐｍ＿ａ＿ａｆｔｅｒ−７）＊（ｐｍ＿ｂ＿ａｆｔｅｒ−５）に置換える。
【０１５６】
以上により生成した「ｐｍ＿ｂ＝（（ｐｍ＿ｂ−５）＊８）＋５；」が右辺の変数を置換えた結果となる。このような変換により、入力写像情報が示す「ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋５」という変換が「ｐｍ＿ｂ−５」により打ち消される。
なお、定数同士の演算は予め行うことができるので、最終的には定数をまとめた式「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８−３５；」とすることができる。
【０１５７】
以上が、ブロックに含まれる変数の置換えとなる。
＜実施形態３の効果＞
実施の形態３では、変数の役割をプログラムの途中で置換える難読化の一例を示した。この難読化方法は以下の３点を特徴とする。
（イ）コントロールフローの始点となるブロックＢ２の入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てている（写像対応表生成部５３３０の処理参照）。
（ロ）各ブロックに、変数の置換えが入口写像情報Ｆ＿ＩＮで示す置換えであった場合に、出口写像情報Ｆ＿ＯＵＴに示す変数の置換えを行う機能が追加されている（ブロック変換部５４００の処理参照）。
（ハ）ブロックＢ５のような複数の分岐元（ブロックＢ２、ブロックＢ４）を持つブロックの全ての分岐元の出口写像情報は、分岐先のブロック（ブロックＢ５）の入口写像情報と等しい（属性情報割当表１８００参照）。
【０１５８】
以上、３点の特徴により、正常系の実行時に難読化後プログラムがどのような実行ルートで実行されても、各ブロックに分岐が発生した際、変数の置換えは、そのブロックの入口写像情報に示す変数の置換えとなる。
このような難読化により、プログラムの様々な位置で変数の役割が置換わり、プログラムの解析を困難にすることができる。また、ブロック毎に、変数の役割が替わることにより、あるブロックでの変数が、他のブロックでどのような役割の変数であるかの解析が困難になる。
＜実施形態４＞
＜概要＞
実施形態１〜３が、対象プログラムにプログラム命令を追加したり、変数の役割を入れ替えて、すなわち変数の値を変えたりすることで難読化プログラムを生成し、ソフトウェアの機密性を確保していたのに対し、本実施形態では、ブロックを暗号化することにより機密性を確保するものである。
【０１５９】
すなわち、本実施形態では、プログラムはブロック毎に暗号化され、外部メモリに記憶されているが、全ブロックが同一の暗号鍵で暗号化されていない点に1つの特徴がある。すなわち、１つのブロックを解析するためには、そのブロックの暗号鍵を求める必要がある事となり、解析に時間を要することと成る。
さらに、実行時に次に実行するブロックを復号化することから、ブロック単位でのみ平文が内部メモリに展開されることとなる。すなわち、メモリ上の平文が少ないため、プログラム全体を解析することをより困難とすることができる。
【０１６０】
ここでは、実施形態３との差異について説明する。
差異は、写像情報が異なる点である。本実施形態の写像対応表６９００を図２３に示す。
写像対応表６９００は、ＩＤ１９１０と写像情報６９２０とで構成され、ＩＤ１９１０は実施形態３と同様に、写像情報６９２０の識別子である。
【０１６１】
すなわち、実施形態３の写像対応表５９００（図２０参照）では、属性に応じて、変数の値が、どの様な演算が施された値であるかが決まったが、本実施形態では、属性に応じて、ブロックを暗号化する暗号鍵が決まることになる。
＜構成＞
図２４は、実施形態４にかかるプログラム難読化装置６０００の構成例を示すブロック図である。
【０１６２】
実施形態３のプログラム難読化装置５０００の構成（図２１参照）と異なる点は、以下の２点である。
１点目は、写像情報生成部６４００の写像対応表生成部６３３０が生成する写像の内容が異なる点である。２点目は、写像の内容が異なることによるブロック変換部６４００で追加するプログラム命令群の生成方法が異なる点である。加えて、ブロック変換部６４００では暗号化も行い難読化プログラム３２００を生成する。
【０１６３】
＜動作＞
以下、写像情報生成部６４００の写像対応表生成部６３３０、ブロック変換部６４００の各処理について説明する。他の動作は、対象プログラムをブロックに分割し、各ブロックに入口属性と出口属性を設定することは、実施形態３と同様である（図１６等参照）。
＜写像情報生成部６４００の写像対応表生成部６３３０の処理＞
本実施形態の写像対応表６９００を図２３に示す。
【０１６４】
写像対応表６９００は、ＩＤ１９１０と写像情報６９２０とで構成され、ＩＤ１９１０は実施形態１と同様に、写像情報６９２０の識別子である。
写像情報６９２０は、暗号鍵の値を示すものである。例えば、属性情報Ｆ１は、「Ｋｅｙ＝３」である。
本実施形態では、各属性に対応する暗号鍵の値は、予め決めてあるものとする。なお、写像対応表生成時にランダムに作成することとしてもよい。
【０１６５】
＜ブロック変換部の処理＞
以下、本実施形態のブロック変換部の処理について、図２５と図２６を用いて説明する。
図２５は、変換後ブロックを示す図であり、図２６は、ブロック変換部の処理を示すフローチャートである。本実施形態では、この変換後ブロックを暗号化して、難読化プログラムを生成する。
【０１６６】
図２４のブロックを参照しながら、図２５のフローチャートに基づいてブロック変換部の処理について説明する。
まず、対象プログラムに復号化関数「decrypt」のプログラムを追加する（ステップＳ６１０、図２５：復号化プログラム６４０９参照）。
この復号化関数は、暗号化するブロックの識別子である「ブロックＩＤ」と、暗号鍵「ｋｅｙ」とを引数とし、「ブロックＩＤ」で特定されるブロックを「ｋｅｙ」で暗号化する機能を有する。なお、ここではブロックの識別子を指定しているが、ブロックの開始アドレスと終了アドレスとを指定することとしてもよく、ブロックが特定できればよい。
【０１６７】
次に、各ブロックに、各ブロックの次に実行するブロック（以下、「次ブロック」という。）を復号するためのプログラム命令を追加する。図２５における、プログラム命令群６４０１〜６４０４である。本実施形態では、最後のブロックＢ５には（ステップＳ６１５：ＹＥＳ）次に実行するブロックは存在しないことから、プログラム命令を追加しないものとする。最後のブロックでない場合は（ステップＳ６１５：ＮＯ）、以下の次ブロックを復号化するようなプログラム命令群を追加する。
【０１６８】
追加するプログラム命令群では、復号化関数を使用して次ブロックを復号化するが、その復号化関数に指定する「ｋｅｙ」、すなわち、復号鍵には、出口写像情報のｋｅｙを設定する。
最初のブロックでは、出口写像情報の値を「ｋｅｙ」に設定する（ブロックＢ１：プログラム命令群６４０１の1行目参照）。例えば、最初のブロックであるブロックＢ１の出口写像情報は「２」であるので、写像情報Ｆ４「ｋｅｙ＝４；」（図２３参照）の「４」を設定する。
【０１６９】
また、他のブロックでは、出口写像情報を入口写像情報から求めるプログラム命令を追加する（ステップＳ６２０）。
例えば、ブロック２では、入口写像情報が「２」、出口写像情報が「４」であり、ｋｅｙはそれぞれ「４」、「５」である（図２３参照）。従って、「４」から「５」を求める式、「ｋｅｙ＝ｋｅｙ＋１；」を追加する（ブロックＢ２：プログラム命令群６４０２の1行目参照）。
【０１７０】
その後に、もとからある分岐命令に、次に実行するブロックの「ブロックＩＤ」と「ｋｅｙ」とを復号関数の引数に設定したプログラム命令を追加したプログラム命令群を追加する（ステップＳ６３０）。
例えば、ブロックＢ２には、「ｄｅｃｒｙｐｔ（Ｂ５、ｋｅｙ）；ｇｏ  ｔｏ  ｌａｂｅｌＥ；」を追加する（ブロックＢ２：プログラム命令群６４０２の２行目参照）。ここで「Ｂ５」は、ブロックＢ５のブロックＩＤとする。
【０１７１】
その後、ブロックを、入口写像情報で示される暗号鍵で暗号化する（ステップＳ６４０）。
例えば、ブロックＢ２は、プログラム命令群６４０２を追加した後、入口写像情報「２」、即ち「Ｋｅｙ＝４」で暗号化する。
すべてのブロックに、ステップＳ６２０〜ステップＳ６４０の処理を行う（ステップＳ６５０）。
【０１７２】
本実施形態の難読化プログラムでは、その実行の際には、メモリ上には実行されているブロックのみが平文として存在することとなり、対象プログラムの全体を把握するのが困難となり、プログラムの解析を困難とすることとなる。
＜補足＞
以上、本発明に係るプログラム難読化装置について実施形態に基づいて説明したが、このプログラム難読化装置を部分的に変形することもでき、本発明は上述の実施形態に限られないことは勿論である。即ち、
（１）実施形態では、第一のブロックと第二のブロックから第三のブロックに分岐がある場合には、第一のブロックの出口写像情報と、第二のブロックの出口写像情報と、第三のブロックの入口写像情報は同じ写像情報としたが、第一のブロックの出口写像情報と、第二のブロックの出口写像情報は別の写像であってもよい。
【０１７３】
例えば、実施形態１においてブロックＢ２の出口写像情報を「ｐｍ＿０＝１２；ｐｍ＿１＝７；」とし、ブロックＢ４の出口写像情報を「ｐｍ＿０＝４、ｐｍ＿１＝１３；」とし、ブロックＢ５の入口写像情報を「ｐｍ＿０＝１２；ｐｍ＿１＝７；」と「ｐｍ＿０＝４、ｐｍ＿１＝１３；」の二つとしてもよい。
この時ブロックＢ５の入口写像情報は、ｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を、（１２、７）または（４、１３）のいずれかに対応させる写像を示すこととなる。
【０１７４】
この時、ブロックＢ５に追加する処理は「（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）＝（１２、７）、（４、１３）」を「（ｐｍ＿０＿ａｆｔｅｒ、ｐｍ＿１＿ａｆｔｅｒ）＝（１３、２１）」に対応させる写像であり、例えば、追加プログラム命令群「ｐｍ＿０＝（ｐｍ＿０−１２）＊（ｐｍ＿０−４）＋１３；ｐｍ＿１＝（ｐｍ＿１−７）＊（ｐｍ＿１−１３）＋２１；」や「ｐｍ＿０＝３＊（ｐｍ＿０−１２）＊（ｐｍ＿１−１３）＋１３；ｐｍ＿１＝４＊（ｐｍ＿０−４）＊（ｐｍ＿１−７）＋２１；」を追加することとなる。
【０１７５】
このような構成により、不正解析者が何らかの解析で第一のブロックの出口写像を知ることができたとしても、第二のブロックの出口情報は知ることができず、解析を困難にできる。
（２）実施形態１における追加変数は、プログラムの引数としてもよい。
引数とした場合は、関数ｆｕｎｃの呼び出し元も変更する必要がある。
【０１７６】
例えば、呼び出し元が「ｆｕｎｃ（ａ、ｂ）；」で、追加変数の初期値が「０」「１」である場合には、呼び出し元を「ｆｕｎｃ（ａ、ｂ、０、１）；」に変更する。
なお、呼び出し元を含むプログラムにおける追加変数の初期値を難読化するために、呼び出し元をさらに本難読化手法を用いて難読化しても構わない。
このような構成により、不正解析者が関数ｆｕｎｃを局所的に解析しても、追加変数の初期値を知ることが困難になる。
（３）実施形態２および実施形態３において、コントロールフローの始点となるブロックの入口写像情報Ｆ＿ＩＮには、もともとのプログラムと同じ変数を割り当てているが、異なる変数としてよい。
【０１７７】
例えば、実施形態２のブロックＢ２の入口写像情報Ｆ１は、「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」としているが、「ｐｍ＿ｂ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ；  ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ｂ＿ｂｅｆｏｒｅ；  ｐｍ＿ｃ＿ａｆｔｅｒ＝  ｐｍ＿ｃ＿ｂｅｆｏｒｅ；」としてもよい。
【０１７８】
このように他の写像とした場合は、関数ｆｕｎｃの呼び出し元も変更する必要がある。
例えば、呼び出し元が「ｆｕｎｃ（ａ、ｂ、ｃ）；」である場合には、写像情報Ｆ１に基づき、呼び出し元を「ｆｕｎｃ（ｂ、ａ、ｃ）；」に変更する。
なお、呼び出し元を含むプログラムを難読化するために、呼び出し元のプログラムをさらに本難読化手法を用いて難読化しても構わない。
【０１７９】
このような構成により、不正解析者が関数ｆｕｎｃを局所的に解析したとしても、変数の置換えの初期値を知ることが困難になる。
（４）実施形態において、写像情報を、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）をｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）に対応させる写像を示したが、サイズの異なる他の変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）に対応させる写像であっても構わない。
【０１８０】
このような構成により、追加するプログラム命令群に例えば掛け算があったとしてもオーバーフローの発生を回避することができる。
よって、追加するプログラム命令群を構成するプログラム命令のバリエーションを増やすことができ、ブロックに含まれるプログラム命令群のうち、どのプログラム命令が追加プログラム命令であり、どのプログラム命令がブロックに元々含まれていたプログラム命令であるかを判断することを困難にすることができる。
【０１８１】
例えば、実施形態３において、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）を１６ｂｉｔのｉｎｔ型変数、ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）を３２ｂｉｔのｌｏｎｇ型変数として、プログラムに変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）を追加する。
この場合、例えば、写像情報Ｆ２を「ｐｍ＿ｄ＿ａｆｔｅｒ＝（ｌｏｎｇ）ｐｍ＿ａ＿ｂｅｆｏｒｅ＊３−４；」とし、追加プログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝（ｐｍ＿ｄ＋４）／３；」としてもよい。
【０１８２】
また、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）を格納する型自体を変えても構わない。
例えば、実施形態３において、変数宣言「ｆ（ｉｎｔ  ｐｍ＿ａ、ｉｎｔ  ｐｍ＿ｂ、ｉｎｔ  ｐｍ＿ｃ）」を「ｆ（ｌｏｎｇ  ｐｍ＿ａ、ｌｏｎｇ  ｐｍ＿ｂ、ｌｏｎｇ  ｐｍ＿ｃ）」として、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＊３−４；」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝（ｐｍ＿ａ＋４）／３；」としてもよい。
（５）実施形態において、写像情報を、ｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）をｐｍ＿Ｘ（Ｘ＝ａ、ｂ、ｃ）に対応させる写像を示したが、他の変数ｐｍ＿Ｙ（Ｙ＝ｄ、ｅ、ｆ）に対応させる写像であっても、他の変数を含むｐｍ＿Ｙ（Ｙ＝ａ、ｂ、ｃ、ｄ、ｅ、ｆ）に対応させる写像であっても構わない。
【０１８３】
例えば、実施形態３において、プログラムに変数「ｐｍ＿ｄ、ｐｍ＿ｅ、ｐｍ＿ｆ」を追加し、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝  ｐｍ＿ａ＿ｂｅｆｏｒｅ／３；ｐｍ＿ｄ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ％３；」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｐｍ＿ａ＝ｐｍ＿ａ＊３＋ｐｍ＿ｄ；」としてもよい。
このような構成により、追加するプログラム命令群を構成するプログラム命令のバリエーションを増やすことができ、ブロックに含まれるプログラム命令群のうち、どのプログラム命令が追加プログラム命令であり、どのプログラム命令がブロックに元々含まれていたプログラム命令であるかを判断することを困難にすることができる。
（６）実施形態３において、写像情報は「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋１４；ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ｂ＿ｂｅｆｏｒｅ＋１２；ｐｍ＿ｃ＿ａｆｔｅｒ＝ｐｍ＿ｃ＿ｂｅｆｏｒｅ−６；」で示されるように、一つの変数（例えば、ｐｍ＿ａ＿ｂｅｆｏｒｅ）の値を用いて１つの変数（例えばｐｍ＿ａ＿ａｆｔｅｒ）を算出する写像を示したが、複数の変数を用いて複数の変数を算出する写像であっても構わない。
【０１８４】
例えば、写像情報Ｆ２を「ｐｍ＿ａ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ＋ｐｍ＿ｂ＿ｂｅｆｏｒｅ；ｐｍ＿ｂ＿ａｆｔｅｒ＝ｐｍ＿ａ＿ｂｅｆｏｒｅ−ｐｍ＿ｂ＿ｂｅｆｏｒｅ」とし、追加するプログラム命令群Ｇ＿２＿ＩＮＶを「ｔｍｐ＝ｐｍ＿ａ；ｐｍ＿ａ＝（ｐｍ＿ａ＋ｐｍ＿ｂ）／２；ｐｍ＿ｂ＝（ｔｍｐ−ｐｍ＿ｂ）／２；」としても構わない。
【０１８５】
このような構成により、変数の役割の置き換えのバリエーションを増やすことができ、解析を困難にすることができる。
（７）実施形態において、写像情報はランダムに生成する場合を示したが、ブロックに含まれるプログラム命令に基づいて写像情報を生成する構成であっても構わない。
例えば、実施形態１において、ブロックＢ５は秘密情報「１２３」を含む。
【０１８６】
この時、ブロックＢ５の出口写像情報における「ｐｍ＿０＿ａｆｔｅｒ」の値を秘密情報の値とし、出口写像情報を「ｐｍ＿０＿ａｆｔｅｒ＝１２３；ｐｍ＿１＿ａｆｔｅｒ＝３１；」としてもよい。
この時、ブロック変換部１４００で、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」を「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０＋ｐｍ＿ｃ；」とすれば、適切な処理結果が得られるようなプログラムに難読化することができる。
【０１８７】
これにより、ランダムに生成した写像情報からプログラム内で用いる値を算出する処理が省けるので、秘密情報を算出する処理を変換したことによる難読化後のプログラムサイズの増加、実行時間の増加を減らすことができる。
（８）実施形態１において、追加変数が２つの場合を示したが、追加変数はいくつであっても構わない。
【０１８８】
追加変数の数を少なくすれば、難読化後のプログラムのサイズを小さく、実行速度を早くすることができ、多くすれば、難読化の効果を大きくすることができる。
（９）実施形態２および実施形態３において、変数の置換え等を行う変数が３つの場合を示したが、置換えを行う変数はいくつであっても構わない。
また、どの変数を置換えるか等をユーザや外部の装置、呼び出し元プログラム等が指定する構成であっても構わない。
（１０）実施形態３では、写像の一例を示したが、逆写像を有する他の写像であっても構わない。
【０１８９】
また、逆写像は必要となる度に、写像から生成する場合を示したが、写像対応表生成部５３３０で生成する写像対応表５９００に、逆写像を記載する欄を設ける構成であっても構わない。
これにより、一度逆写像を生成すれば、それ以降の同一の逆写像の生成が必要なくなるので、難読化処理を高速化することができる。
【０１９０】
また、写像情報Ｆ＿Ｘに対応して追加するプログラム命令群Ｆ＿Ｘ、写像情報Ｆ＿Ｘの逆写像であるＦ＿Ｘ＿ＩＮＶに対応して追加するプログラム命令群Ｆ＿Ｘ＿ＩＮＶを写像対応表に記載する構成であっても構わない。
これにより、同一の写像情報や逆写像情報について、複数回、同様のプログラム命令群を生成する手間が省けるので、難読化処理を高速化することができる。
【０１９１】
また、ここで述べた写像、逆写像、追加プログラム命令群Ｆ＿Ｘ、追加プログラム命令群Ｆ＿Ｘ＿ＩＮＶをユーザが指定する構成であっても構わない。
（１１）実施形態では、対象プログラムが、Ｃ言語で作成されているプログラムである場合を示したが、Ｊａｖａ（登録商標）言語、Ｊａｖａ（登録商標）バイトコード、Ｃ＋＋言語、機械語、アセンブリ言語、コンパイラ等の中間言語、ＵＭＬ（UnifiedModeling Language）等のモデリング言語等の他のプログラム言語で作成されたものであっても構わない。
【０１９２】
また、対象プログラムは、論理回路記述言語等で記述された論理回路の設計データであってもよい。
さらに、実施形態では、Ｃ言語の難読化対象プログラムを難読化してＣ言語の難読化後プログラムを生成することとしているが、難読化後プログラムを機械語として出力する構成であっても構わない。
【０１９３】
また、難読化対象プログラムはＣ言語のプログラムでなくＵＭＬで記載された構造であって、難読化後プログラムはＪａｖａ（登録商標）等の言語であっても構わない。
（１２）実施形態において、変数「ｐｍ＿Ｘ」が取りうる値を要素とする集合ＰＭ＿Ｘは、変数の型によって決めるものであっても、予めユーザが指定するものであっても構わない。
（１３）実施形態において、プログラム命令群をブロックの先頭に追加する場合を示したが、それら以外の位置に追加する構成であっても構わない。
【０１９４】
例えば、実施形態２におけるプログラム変換部５４００の処理で、追加するプログラム命令群Ｇ＿２＿４「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；」を、ブロックＢ２に含まれるプログラム命令「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」の後に追加しても構わない。
この場合、追加したプログラム命令群より前のプログラム命令は、ブロックＢ２の入口写像情報に基づき変数の置換えを行い、追加したプログラム命令群よりも後のプログラム命令は、ブロックＢ２の出口写像情報に基づき変数の置換えを行う。
【０１９５】
ここでは、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」をブロックＢ２の入口写像情報Ｆ２に対して基づき変数の置換えを行い「ｐｍ＿ｃ＝ｐｍ＿ｃ＊８；」とする。
このような構成にすることによって、追加プログラム命令群が含まれる位置がブロックによって異なるようになり、変換後ブロックを見て、どのプログラム命令が追加プログラム命令であり、どのプログラム命令が元々ブロックに存在していたプログラム命令であるかを解析しにくくすることができる。
【０１９６】
また同様に、追加プログラム命令群の途中に元々ブロックに存在していたプログラム命令が挟まれる構成であっても構わない。このようにすることで、どのプログラム命令群が元々ブロックに存在していたものであるかをさらに解析しにくくすることができる。
（１４）実施形態１における秘密ブロック変換部１５００において、置換えを行う秘密情報は、ユーザ等が指定した秘密情報を置換える構成であっても、プログラムに含まれる全ての定数値を置換える構成であっても構わない。
【０１９７】
また、プログラムに含まれる定数値を一定の確率で置換える構成であったり、ランダムに選択したものを置換える構成であっても構わない。
このようにすることで、全ての秘密情報を置き換える場合よりも高速に難読化を行うことができる。また、難読化により増加する処理の数を抑えることができるため、難読化後のプログラムの動作も高速化することができる。
（１５）実施形態１では、追加プログラム命令群Ｇ＿１＿２の一例を示したが、（０、１）を（３０、６）に対応させる写像を実現するプログラム命令群であればどのようなものでも構わない。他の写像を実現するプログラム命令群についても同様である。
【０１９８】
また、追加プログラム命令群の生成の仕方も実施形態に示したやり方に限るものではなく、他のやり方であっても構わない。
すなわち、入力写像情報が与えられた場合に出力写像情報に従った変換が行われるようなプログラム命令群が生成されるのであればどのようなものであっても構わない。
（１６）実施形態１では、写像情報をｐｍ＿０＿ｂｅｆｏｒｅ∈ＰＭ＿０、ｐｍ＿１＿ｂｅｆｏｒｅ∈ＰＭ＿１を満たす全ての（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を１点（例えば（０、１））に対応させる写像を示したが、複数の点に対応させる写像であっても構わない。
【０１９９】
例えば、写像情報Ｆ２を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（１、２）または（４、５）のいずれかに対応させる写像とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（５、６）または（８、９）とし、追加プログラム命令群Ｇ＿２＿４を例えば、（１、２）を（５、６）に対応させ、（４、５）を（８、９）に対応させる写像を実現するプログラム命令群とする。
【０２００】
この場合、追加プログラム命令群Ｇ＿２＿４は、例えば「ｐｍ＿０＝ｐｍ＿０＋４；ｐｍ＿１＝ｐｍ＿１＋４；」のようなものとなる。
また、追加プログラム命令群が追加変数以外の変数を含む構成であっても構わない。
例えば、写像情報Ｆ２を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（０、１）または（３、４）のいずれかに対応させる写像とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（０、１）または（１、２）のいずれかに対応させる写像とし、追加プログラム命令群Ｇ＿２＿４を例えば、「ｐｍ＿０＝ｐｍ＿０％３＋ｐｍ＿ａ％２；ｐｍ＿１＝ｐｍ＿１％３＋ｐｍ＿ａ％２；」としてもよい。
【０２０１】
このように写像情報を用いて特定変数の値を複数の点に対応させる代わりに、集合を用いることとしてもよい。
例えば、写像情報Ｆ２を、（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（６の倍数、３で割って１余る数）に対応させる集合とし、写像情報Ｆ４を（ｐｍ＿０＿ｂｅｆｏｒｅ、ｐｍ＿１＿ｂｅｆｏｒｅ）を（６で割って１余る数、３で割って２余る数）に対応させる集合とし、追加プログラム命令群Ｇ＿２＿４を例えば、「ｐｍ＿０＝ｐｍ＿０＋１；ｐｍ＿１＝（ｐｍ＿１−１）＊２＋２；」としてもよい。
【０２０２】
このような構成を用いれば、追加変数以外の変数の値によって、追加プログラム命令群を実行した後の追加変数の値が替わる。よって、不正解析者が、どの変数が追加変数であって、どの変数が元々プログラムに含まれる変数であるかを解析することが困難になる。
この効果をより具体的に説明する。追加変数以外の変数を使わない場合、不正解析者が、ブロックの出口写像情報、入口写像情報を解析するために、関数の引数の値を変えて、関数ｆｕｎｃを複数回実行し、実行時にメモリに現れる値（ランタイムデータ）を収集し、その差分をとり、不変なデータを抽出することで写像情報の追加変数の値の特定が可能なる。
【０２０３】
これに対し、上記の構成を用いれば、追加プログラム命令群を実行した後のｐｍ＿０、ｐｍ＿１は固定の値とならないため、写像情報の解析が困難になる。また、写像情報を格納する変数がどの変数であるかの解析も困難になる。
なお、ランタイムデータを収集する不正解析については、「署名生成ソフトウェアのランタイムデータ探索による耐タンパー性評価  ＳＣＩＳ２００５」に記載されている。
【０２０４】
なお、追加変数以外の変数とは、必ずしも難読化対象プログラムに含まれる変数でなくてもよい。例えば、ＲＯＭ、ＲＡＭ、レジスタ、キャッシュ等に保持されている値であっても構わない。
（１７）実施形態１における秘密ブロック変換部１５００の処理において、置換えを行う秘密情報は、例えばプログラムの分岐先のアドレスのようなプログラムの分岐先を示す数値であっても構わない。
【０２０５】
例えば、実施形態１における秘密ブロック変換部１５００の処理において、ブロックＢ２の無条件分岐命令「ｇｏｔｏ  ｌａｂｅｌＥ；」を条件分岐命令「ｓｗｉｔｃｈ（２）｛ｃａｓｅ  １：ｇｏｔｏ  ｌａｂｅｌＣ；  ｃａｓｅ  ２  ｇｏｔｏ  ｌａｂｅｌＥ：｝」に置換える。
この条件分岐命令は、難読化対象プログラムに含まれるラベル「ｌａｂｅｌＥ：」「ｌａｂｅｌＣ：」が条件分岐先であり、条件式は、もともとの無条件分岐先「ｌａｂｅｌ  Ｅ；」に対応するｃａｓｅ文の値「２」としたものである。
【０２０６】
次に条件式「２」を、秘密ブロック変換部１５００の処理で述べた方法を用いてブロックＢ２の出口写像情報に基づき追加変数を用いたプログラム命令に置換える。
さらに、実施形態１では、秘密情報を式に置き換えているが、プログラム命令を追加するだけでもよい。
例えば、実施形態１では、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」を「ｐｍ＿ｂ＝ｐｍ＿ｂ＊（３＊ｐｍ＿０＋４＊ｐｍ＿１−４０）＋ｐｍ＿ｃ；」に置き換えているが（図１３、図１４参照）、１プログラム命令を追加することとしてもよい。
【０２０７】
具体的には、「ｐｍ＿０」は、ブロックＢ５の出口属性「１０」であり、「ｐｍ＿０＝１３」であるので、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０／１３；」を追加して、「ｐｍ＿ｂ＝ｐｍ＿ｂ＊ｐｍ＿０／１３  ；  ｐｍ＿ｂ＝ｐｍ＿ｂ＊１２３＋ｐｍ＿ｃ；」としてもよい。
このような構成により、プログラムの実行順序の解析を困難にすることができる。
（１８）各部は、必ずしも独立した部である必要はなく、複数の部が提供する機能を組み合わせた部とする構成であっても構わない。
（１９）実施形態１では、難読化対象プログラムに変数を追加する変数追加手段がある構成を示したが、追加変数の替わりに、難読化対象プログラムにおいて使われていない変数を使う構成であっても構わない。
（２０）実施形態における、ブロック変換部の処理において、入口写像情報と出口写像情報が同じ写像情報であるブロックには、追加プログラム命令を追加しない構成であっても構わない。
【０２０８】
そのような構成にすることで、難読化後プログラムのサイズを削減し、実行時間を短縮することができる。
また、属性情報割当表１８００において、異なる属性を同一の属性に置換えてもよい。例えば、実施形態で用いた属性情報割当表１８００の属性１８３１「４」を「２」としてもよい（図９参照）。ブロックＢ２出口属性、ブロックＢ４出口属性およびブロックＢ５入口属性の３つである。
【０２０９】
このような構成を用いると、入口写像情報と、出口写像情報が同一となるブロックが増え、さらに難読化後のプログラムのサイズの削減、実行時間の短縮を行うことができる。
（２１）本発明は、実施形態１と実施形態３を組み合わせた構成であっても構わない。
このような構成を用いると、いずれの変数が追加変数であり、いずれの変数が元々プログラムに含まれる変数であるかの解析が困難になる。
【０２１０】
また、実施形態１と実施形態２、実施形態４、変形例（補足（１）等）との組み合わせであってもよい。
（２２）実施形態では、難読化対象プログラムを基本ブロックに分割する構成を示したが、その他の分割の仕方であっても構わない。
例えば、基本ブロックをさらに複数のブロックに分割してもよい。例えば、基本ブロックが「ａ＝１；ａ＝ａ＊２；ａ−３；」である場合に、それぞれのプログラム命令をブロックとし、「ａ＝１；」「ａ＝ａ＊２；」「ａ−３；」をそれぞれブロックする。その場合、「ａ＝１；」のブロックから「ａ＝２；」のブロックへは分岐があると見なして、コントロールフローを生成する。このようにすることにより、基本ブロックよりもさらに細かい単位で追加プログラム命令群を入れることができるため、より解析を困難にすることができる。
【０２１１】
また、例えば、基本ブロックとは無関係にブロックを生成しても構わない。
その場合、追加プログラム命令は、そのブロックにおける最後の合流点よりも後であって、最初の分岐点よりも前に追加する。もし、そのブロックにおける最後の合流点よりも後であって、最初の分岐点よりも前であるプログラム命令群が１つもない場合には、そのブロックの入口写像情報と出口写像情報とは同じ写像情報とする。
【０２１２】
なお、分岐点とは分岐命令（条件分岐命令および無条件分岐命令）がある位置であり、合流点とは分岐命令によって分岐する分岐先の位置である。
（２３）実施形態においるブロック変換部１４００の処理では、プログラム命令を追加することによって、ブロックに機能を追加する構成を示したが、必ずしもこのような構成でなくとも構わない。
【０２１３】
例えば、ブロックを構成するプログラム命令のうちのいくつかの命令であるプログラム命令群１を取り除き、このプログラム命令群１と追加する機能の両方の処理を行うプログラム命令群を追加する構成であっても構わない。
例えば、実施形態２において、ブロックＢ２からプログラム命令「ｐｍ＿ｂ＝ｐｍ＿ｂ＊８；」を取り除き、プログラム命令群Ｄ「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ＊８；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；」を追加する構成であっても構わない。
【０２１４】
ここで、プログラム命令群Ｄは、変換後ブロックＢ２のプログラム命令群  「ｔｍｐ＝ｐｍ＿ａ；  ｐｍ＿ａ＝ｐｍ＿ｃ；  ｐｍ＿ｃ＝ｐｍ＿ｂ；  ｐｍ＿ｂ＝ｔｍｐ；  ｐｍ＿ａ＝ｐｍ＿ａ＊８；」（図１７参照）の２番目のプログラム命令「ｐｍ＿ａ＝ｐｍ＿ｃ；」と５番目のプログラム命令「ｐｍ＿ａ＝ｐｍ＿ａ＊８；」をまとめて行う処理に置換えたプログラム命令群である。
（２４）上記の実施の形態では、写像情報の基づいた変数の置き換え等を例として挙げたが、これに限られるものではない。
【０２１５】
上記の実施の形態では、ブロック間で引き継ぐ秘密情報算出用の変数等について、ブロックから出る時の値と次のブロックに入る時の値とを揃え、各ブロックから出力される時点での値が次のブロックの入力として期待される値となるような範囲で各ブロックを難読化する等しているが、同様の性質を持つ難読化変換も本発明に含まれる。
例えば、実施形態４のように、分岐先のブロックを暗号化し、分岐元のブロックへそのブロックを復号する処理を追加するなどしてもよい。
【０２１６】
また、分岐先のブロックにブロック中の命令の偽装を行う変換を施し、分岐元へその偽装の解除を行う処理を追加するなどしてもよい。
すなわち、本発明は、分岐元のブロックと分岐先のブロックとで相殺しあうような性質を有する難読化を施すことによって、プログラムの制御構造に関わらない難読化を行うことを可能とするものである。
【０２１７】
（２５）上記の各装置は、具体的には、マイクロプロセッサ、ＲＯＭ、ＲＡＭ、ハードディスクユニット、ディスプレイユニット、キーボード、マウスなどから構成されるコンピュータシステムである。前記ＲＡＭまたはハードディスクユニットには、コンピュータプログラムが記憶されている。前記マイクロプロセッサが、前記コンピュータプログラムにしたがって動作することにより、各装置は、その機能を達成する。ここでコンピュータプログラムは、所定の機能を達成するために、コンピュータに対する指令を示す命令コードが複数個組み合わされて構成されたものである。
【０２１８】
（２６）上記の各装置を構成する構成要素の一部または全部は、１個のシステムＬＳＩ（Large Scale Integration：大規模集積回路）から構成されているとしてもよい。システムＬＳＩは、複数の構成部を１個のチップ上に集積して製造された超多機能ＬＳＩであり、具体的には、マイクロプロセッサ、ＲＯＭ、ＲＡＭなどを含んで構成されるコンピュータシステムである。前記ＲＡＭには、コンピュータプログラムが記憶されている。前記マイクロプロセッサが、前記コンピュータプログラムにしたがって動作することにより、システムＬＳＩは、その機能を達成する。
【０２１９】
（２７）上記の各装置を構成する構成要素の一部または全部は、各装置に脱着可能なＩＣカードまたは単体のモジュールから構成されているとしてもよい。前記ＩＣカードまたは前記モジュールは、マイクロプロセッサ、ＲＯＭ、ＲＡＭなどから構成されるコンピュータシステムである。前記ＩＣカードまたは前記モジュールは、上記の超多機能ＬＳＩを含むとしてもよい。マイクロプロセッサが、コンピュータプログラムにしたがって動作することにより、前記ＩＣカードまたは前記モジュールは、その機能を達成する。このＩＣカードまたはこのモジュールは、耐タンパ性を有するとしてもよい。
【０２２０】
（２８）本発明は、上記に示す方法であるとしてもよい。また、これらの方法をコンピュータにより実現するコンピュータプログラムであるとしてもよいし、前記コンピュータプログラムからなるディジタル信号であるとしてもよい。
（２９）また、本発明は、前記コンピュータプログラムまたは前記ディジタル信号をコンピュータ読み取り可能な記録媒体、例えば、フレキシブルディスク、ハードディスク、ＣＤ−ＲＯＭ、ＭＯ、ＤＶＤ、ＤＶＤ−ＲＯＭ、ＤＶＤ−ＲＡＭ、ＢＤ（Ｂｌｕ−ｒａｙ  Ｄｉｓｃ）、半導体メモリなどに記録したものとしてもよい。また、これらの記録媒体に記録されている前記ディジタル信号であるとしてもよい。
【０２２１】
（３０）また、本発明は、前記コンピュータプログラムまたは前記ディジタル信号を、電気通信回線、無線または有線通信回線、インターネットを代表とするネットワーク、データ放送等を経由して伝送するものとしてもよい。
（３１）また、本発明は、マイクロプロセッサとメモリを備えたコンピュータシステムであって、前記メモリは、上記コンピュータプログラムを記憶しており、前記マイクロプロセッサは、前記コンピュータプログラムにしたがって動作するとしてもよい。
【０２２２】
（３２）また、前記プログラムまたは前記ディジタル信号を前記記録媒体に記録して移送することにより、または前記プログラムまたは前記ディジタル信号を前記ネットワーク等を経由して移送することにより、独立した他のコンピュータシステムにより実施するとしてもよい。
＜従来技術の詳細および課題＞
図２７は、従来の難読化方法の例を示すプログラム例である。
【０２２３】
＜オリジナルプログラム＞
難読化前のオリジナルプログラムを図２７（ａ）に示す。このプログラムにおいて、「１２３４」は不正解析者に知られたくない秘密情報９００１である。なお、以下では特に断らない限り、Ｃ言語で記述されたプログラムを例とした説明を行う。
図２７（ａ）に示す難読化前のプログラムでは、このプログラムに含まれる定数を全て収集することで秘密情報９００１の値を絞りこむことができる。すなわち、図２７（ａ）に含まれる定数を収集すると、「１」、「２」、「７」、「５」、「１２３４」が収集できるが、そのうちの一つは秘密情報の値である。よって、不正解析者は、プログラムに含まれる定数を収集するだけで秘密情報の値を５つに絞りこむことができる。
【０２２４】
＜秘密情報置換え後プログラム＞
プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換したプログラムを図２７（ｂ）に示す。
このプログラムは、オリジナルプログラム（ａ）に新しい変数「ｃ」を追加し、追加した変数「ｃ」を用いて秘密情報「１２３４」を算出する処理を追加し、秘密情報「１２３４」を「ｃ（９００２）」に置換えることで生成したプログラムである。
【０２２５】
この図では、「ｃ＝１；ｃ＝ｃ＊１０＋２；ｃ＝ｃ＊１０＋３；ｃ＝ｃ＊１０＋４；」が秘密情報「１２３４」を算出するプログラム命令群である。
図２７（ｂ）のプログラムでは、プログラムに含まれる定数を全て収集しても秘密情報「１２３４」が直接得られることはない。
よって、図２７（ａ）のプログラムよりも安全性が高い。
【０２２６】
しかし、不正解析者がプログラムの処理自体を解析する等して「ａ＝ａ＋ｂ＋ｃ；」の「ｃ」が秘密情報９００１であると判断した場合、秘密情報を算出する処理「ｃ＝１；」「ｃ＝ｃ＊１０＋２；」「ｃ＝ｃ＊１０＋３；」「ｃ＝ｃ＊１０＋４；」を順に実行することでｃ９００２の値が順に「１」、「１２」、「１２３」、「１２３４」となることを解析し、秘密情報の値「１２３４」を解析することができる。
【０２２７】
＜秘密情報拡散後プログラム＞
続いて、秘密情報を算出する処理をプログラム中の様々な位置に拡散したプログラムを図２７（ｃ）に示す。このプログラムは、図２７（ｂ）で示した秘密情報置換え後プログラムに含まれる秘密情報を算出するプログラム命令「ｃ＝１；」、「ｃ＝ｃ＊１０＋２；」、「ｃ＝ｃ＊１０＋３；」、「ｃ＝ｃ＊１０＋４；」をプログラム中の様々な位置に拡散したプログラムである。
【０２２８】
秘密情報置換え後プログラム図２７（ｂ）では、秘密情報を算出するための処理が一箇所にまとまっていたのに対し、図２７（ｃ）では様々な位置に拡散されたことで、秘密情報を算出する処理を見つけ出すことが困難になる。
また、以上で述べた難読化方法の他にも、非特許文献１には、計算途中の値を記憶する変数のメモリをプログラム実行中に何度か変えることでプログラムの解析が困難になることが述べられている。図２７（ｄ）は、このような難読化の一例として、変数の役割をプログラムの途中で変えるプログラムを示す。
【０２２９】
＜変数の役割をプログラムの途中で変えるプログラム＞
変数の役割をプログラムの途中で変えるプログラムを図２７（ｄ）に示す。このプログラムはオリジナルプログラム図２７（ａ）に変数ｄ、ｅを追加し、プログラムの途中に「ｄ＝ａ；ｂ＝ｅ；」を追加して、追加した位置以降の変数「ａ」、「ｂ」をそれぞれ「ｄ」、「ｅ」に置換えたプログラムである。
【０２３０】
すなわち、オリジナルプログラムの途中に「ｄ＝ａ；ｂ＝ｅ；」（プログラム命令９００３）を追加して、追加した位置以降のプログラム命令群において変数「ａ」、「ｂ」をそれぞれ「ｄ」、「ｅ」に置換え、「ａ＝ａ＜＜５；ａ＝ａ＊ｂ；ａ＝ａ＋ｂ＋１２３４；ｕｓｅ（ａ）」を「ｄ＝ｄ＜＜５；ｄ＝ｄ＊ｅ；ｄ＝ｄ＋ｅ＋１２３４；ｕｓｅ（ｄ）」としたプログラムである。
【０２３１】
このプログラムでは、プログラムの途中から、変数「ａ」、「ｂ」の役割を「ｄ」、「ｅ」が行うことになる。そのため、秘密情報の算出に用いる変数がどれであるのかを追跡しにくくなる。
＜課題＞
プログラムに含まれる秘密情報を、複数のプログラム命令を実行することによって算出されるように変換し、さらに、そのプログラム命令をプログラム中の様々な場所に拡散することで解析を困難にする方法がある。しかし、制御構造が複雑なプログラムに対して拡散を行うことは困難であるため、不正解析者は特定の箇所を重点的に解析することにより比較的容易に秘密情報を得ることができてしまうという課題がある。以下、この課題を具体的に説明する。
【０２３２】
（ａ）オリジナルプログラム
図２８は難読化前のオリジナルプログラムを示す。オリジナルプログラムは関数ｆｕｎｃを含み、関数はプログラム命令群９１１０からなる関数である。また、「１２３」が秘密情報である（プログラム命令９１０１参照）。
このプログラムのコントロールフローを図２９に示す。
【０２３３】
コントロールフローは、プログラムにおける分岐や合流といった制御の流れをグラフで表現したものであり、一般に制御フローグラフと呼ばれるものである。コントロールフローの生成は、例えば次の基本ブロック生成ステップと、グラフ生成ステップとからなる。
基本ブロック生成ステップは、難読化対象プログラムから基本ブロックを生成するステップである。基本ブロックとは、１以上のプログラム命令からなるプログラム命令群であって、プログラム命令群の先頭以外では他のブロックから合流せず、プログラム命令群の最後以外では他のブロックへ分岐しないプログラム命令群である。
【０２３４】
より詳細には、基本ブロックは、プログラムの入口のプログラム命令（プログラムの一番最初に実行されるプログラム命令）、または、処理が合流するプログラム命令、または、分岐となるプログラム命令の次のプログラム命令を開始プログラム命令とし、次に処理が合流するプログラム命令の一つ前のプログラム命令、または、プログラムの出口の命令（プログラムの一番最後に実行される命令）、または分岐となるプログラム命令を終了プログラム命令とし、開始プログラム命令から終了プログラム命令までに存在するプログラム命令からなるプログラム命令群である。
【０２３５】
基本ブロック生成ステップでは、難読化対象プログラムを分割して複数の基本ブロックを生成し、難読化対象プログラムを構成する全てのプログラム命令は、基本ブロック生成ステップにより、いずれかの一つの基本ブロックに含まれるように分割を行う。
グラフ生成ステップでは、次の処理を行う。
基本ブロックのそれぞれをノードと見なし、第一のノードに第二のノードへの分岐命令（ｇｏｔｏ文、ｂｒｅａｋ文、ｃｏｎｔｉｎｕｅ文、ｒｅｔｕｒｎ文による無条件分岐命令、またはｆｏｒ文、ｗｈｉｌｅ文、ｄｏ−ｗｈｉｌｅ文、ｉｆ文、ｓｗｉｔｃｈ文による条件分岐命令のこと）がある場合、または、第一のノードの最後のプログラム命令が無条件分岐命令以外のプログラム命令であって、前記最後のプログラム命令に対応するプログラム上のプログラム命令の一つ後のプログラム命令が対応するプログラム命令が第二のノードであった場合に、第一のノードと第二のノードの間にはエッジが存在すると見なし、ノードとエッジからなるグラフを生成する。
【０２３６】
図２９において、ブロック９１１１〜９１１５はプログラムを複数のプログラム命令群に分割したブロックを示す。各ブロックは１以上のプログラム命令からなるプログラム命令群である。また、矢印は制御の流れとエッジを示す。
ブロック９１１１からは２つの矢印が出ているが、デバッガ等でプログラムの実行手順を強制的に変えるなどを行わないような実行時、すなわち、正常系での実行時にブロック９１１１が実行された後に、ブロック９１１２かブロック９１１３のどちらかが実行されることを示す。ブロック９１１５は、秘密情報である値「１２３」を含む。
【０２３７】
（ｂ）秘密情報置換え後プログラムのコントロールフロー
図３０は、図２７（ｂ）と同様に、オリジナルプログラム図２７（ａ）に新しい変数「ｃ」を追加し、追加した変数「ｃ」を用いて秘密情報「１２３」を算出する処理を追加し、秘密情報「１２３」を「ｃ」に置換えることで生成したプログラムのコントロールフロー図である。
【０２３８】
すなわち、ブロック９２１１中で「ｃ＝１；」と変数ｃの初期化を行い、ブロック９２１５で「ｃ＝ｃ＊１０＋２；ｃ＝ｃ＊１０＋３；」という計算を行わせることにより、変数ｃに「１２３」という値が算出されるようにしている。
（ｃ）秘密情報拡散後プログラムのコントロールフロー
図３０に示した秘密情報を算出するプログラム命令をプログラム中の様々な位置に拡散したプログラムを図３１に示す。
【０２３９】
以下、図３０のプログラムから図３１のプログラムのコントロールフローを生成する手順を説明する。
まず、ブロック９２１５に含まれるプログラム命令「ｃ＝ｃ＊１０＋２；」を移動する場所を決める（図３０参照）。
ここで、このプログラム命令は、条件分岐の片側に移動することはできない。このような制限が設けられる理由は、例えば、ブロック９１１４にこのプログラム命令を移動すると、ブロック９１１４が実行されずにブロック９１１２が実行される分岐が起こった場合に、このプログラム命令「ｃ＝ｃ＊１０＋２；」が実行されないためである。この場合、ブロック９２１５におけるｃの値が「１２３」ではなくなってしまうため、適切な演算が行えなくなる。
【０２４０】
同様に、このプログラム命令はループの中身に入れることもできない。これは、例えば、ブロック９１１３にこのプログラム命令を移動すると、ブロック９１１３が実行される回数によってこのプログラム命令「ｃ＝ｃ＊１０＋２；」が実行される回数が変わってしまうためである。この場合、「ｃ＝ｃ＊１０＋２；」が２回以上実行されると、ブロック９２１５におけるｃの値が「１２３」と異なる値となってしまい、適切な演算が行えなくなる。
【０２４１】
よって、本プログラム例ではｃの値が最終的に「１２３」となることを保証するために、このプログラム命令「ｃ＝ｃ＊１０＋２；」をブロック９３１１に移動することとなる（図３１参照）。同様に「ｃ＝ｃ＊１０＋３；」も同様にブロック９３１１に移動することとなり、図３１に示すコントロールフローのプログラムが生成される。
このように、従来手法では、分岐やループを含むプログラムでは、プログラム命令を移動可能な位置は少なく、結果として、プログラム命令は十分に拡散されずに特定の箇所に集中してしまう。よって、従来手法では、プログラム命令の拡散が困難な箇所（分岐やループ等）以外の箇所を重点的に解析することにより、秘密情報を算出するプログラム命令群を比較的容易に見つけ出すことができてしまうという課題がある。
【０２４２】
さらに、非特許文献１では、計算途中の値を記憶する変数のメモリをプログラムの途中で変えることでプログラムの解析が困難になることが述べられている。
しかし、制御構造が複雑なプログラムに対してこの手法を行う際にも、上記と同様の課題がある。以下、この課題を具体的に説明する。
難読化前のオリジナルプログラムは前記と同じく図２８のプログラムであるとする。また、プログラムのコントロールフローは図２９のコントロールフローとなる。このプログラムの途中で変数の役割を置換える。
【０２４３】
変数の入れ替えを分岐の片側で行なうことはできない。
例えば、ブロック９１１４の最後に変数の役割を入れ替えるための命令「ｄ＝ａ；ｅ＝ｂ；」を追加した場合、ブロック９１１５に含まれるプログラム命令群「ｌａｂｅｌＥ：  ｂ＊＝ａ＊１２３；ｒｅｔｕｒｎ  ｂ；」において、「ａ」、［ｂ］を「ｄ」、「ｅ」に置換え「ｌａｂｅｌＥ：；  ｅ＊＝ｄ＊１２３；ｒｅｔｕｒｎ  ｅ；」としなければならない。
【０２４４】
しかし、このように置換えると、ブロック９１１４が実行されずにブロック９１１５が実行される場合、すなわち、ブロック９１１１の後にブロック９１１２が実行される分岐が行われた場合に、「ｄ＝ａ；ｅ＝ｂ；」が実行されないまま、ブロック９１１５が実行されることになる。
この場合、ｄおよびｅの値がａおよびｂの値と異なってしまうので、正しい演算結果が得られなくなる。よって、プログラム命令を拡散させる際と同様に、分岐の片側で入れ換えを行うことを避け、ブロック９１１１に変数の役割を入れ替えを行う処理を追加することとなる。そのため、変数の役割を入れ替える処理を多数追加しようとしても、このような処理がブロック９１１１に集中してしまうため、処理を見つけ出し易くなってしまうという課題がある。
【０２４５】
以上の例に見られるように、従来の難読化方法でプログラムに含まれる処理を複雑にする変換を行っても、プログラムの解析を困難にする難読化の方法として、その制御構造によっては複雑にしにくいものがあるという課題がある。
【産業上の利用可能性】
【０２４６】
本発明は、プログラムを従来技術よりも解析困難なように難読化することができるので、暗号鍵等の秘密情報を扱うプログラムの難読化装置等の分野で有用である。
【図面の簡単な説明】
【０２４７】
【図１】本発明にかかるプログラム難読化装置のコンピューティングシステムの例である。
【図２】プログラム難読化装置１０００の構成例を示すブロック図である。
【図３】難読化の対象プログラム２０００の例を示す図である。
【図４】対象プログラムを難読化した後の難読化プログラム３０００の例を示す図である。
【図５】プログラム難読化装置１０００の難読化処理を表すフローチャートである。
【図６】追加変数が追加された対象プログラム２１００を示す図である。
【図７】ブロック分割部１２００が対象プログラム２１００から生成した基本ブロックであるブロックＢ１〜ブロックＢ５を示す図である。
【図８】対象プログラム２１００のコントロールフローを示す図である。
【図９】属性情報割当表生成部１３２０が生成する属性情報割当表１８００の生成過程と、構成及び内容の例を示す図である。
【図１０】属性情報割当表生成処理を表すフローチャートである。
【図１１】各ブロックの入口と出口に設定された属性を示した、コントロールフローである。
【図１２】写像対応表１９００の構成および内容の例を示す図である。
【図１３】ブロックＢ１〜ブロックＢ５を、ブロック変換部１４００が変換して生成した変換後ブロックを示す図である。
【図１４】変換後の秘密ブロックを含む難読化後プログラム３０００を示す図である。
【図１５】実施形態２の写像対応表４９００の構成および内容の例を示す図である。
【図１６】実施形態２にかかるプログラム難読化装置４０００の構成例を示すブロック図である。
【図１７】ブロック変換部４４００によって変換して生成した変換後ブロックＢ２を示す図である。
【図１８】ブロックＢ２の入口と出口での変換を示す図である。
【図１９】プログラム命令群Ｇ＿２＿４による置換えを示す図である。
【図２０】実施形態３の写像対応表５９００の構成および内容の例を示す図である。
【図２１】実施形態３にかかるプログラム難読化装置５０００の構成例を示すブロック図である。
【図２２】ブロック変換手段５４００によって変換して生成した変換後ブロックＢ２を示す図である。
【図２３】実施形態４の写像対応表６９００の構成および内容の例を示す図である。
【図２４】実施形態４にかかるプログラム難読化装置６０００の構成例を示すブロック図である。
【図２５】実施形態４の変換後ブロックを示す図である。
【図２６】ブロック変換部の処理を示すフローチャートである。
【図２７】従来の難読化方法の一例を示す概念図である。
【図２８】難読化前のオリジナルプログラム９１００を示す図である。
【図２９】オリジナルプログラム９１００のコントロールフローを示す図である。
【図３０】秘密情報を算出するプログラム命令を配置した難読化後のプログラムのコントロールフローを示す図である。
【図３１】秘密情報を算出するプログラム命令を拡散した難読化後のプログラムのコントロールフローを示す図である。
【符号の説明】
【０２４８】
１０    コンピューティングシステム
１０００  ４０００  ５０００    プログラム難読化装置
１１００    変数追加部
１２００    プログラム分割部
１３００    写像情報生成部
１３１０    コントロールフロー生成部
１３２０    属性情報割当表生成部
１３３０    写像対応表生成部
１４００    ブロック変換部
１５００    秘密ブロック変換部
１８００    属性情報割当表
１９００  ４９００  ５９００  ６９００    写像対応表
２０００  ２１００    対象プログラム
３０００    難読化プログラム
９１００    オリジナルプログラム
【手続補正３】
【補正対象書類名】図面
【補正対象項目名】全図
【補正方法】変更
【補正の内容】
【図１】
2007091558.tif 000034
【図２】
2007091558.tif 000035
【図３】
2007091558.tif 000036
【図４】
2007091558.tif 000037
【図５】
2007091558.tif 000038
【図６】
2007091558.tif 000039
【図７】
2007091558.tif 000040
【図８】
2007091558.tif 000041
【図９】
2007091558.tif 000042
【図１０】
2007091558.tif 000043
【図１１】
2007091558.tif 000044
【図１２】
2007091558.tif 000045
【図１３】
2007091558.tif 000046
【図１４】
2007091558.tif 000047
【図１５】
2007091558.tif 000048
【図１６】
2007091558.tif 000049
【図１７】
2007091558.tif 000050
【図１８】
2007091558.tif 000051
【図１９】
2007091558.tif 000052
【図２０】
2007091558.tif 000053
【図２１】
2007091558.tif 000054
【図２２】
2007091558.tif 000055
【図２３】
2007091558.tif 000056
【図２４】
2007091558.tif 000057
【図２５】
2007091558.tif 000058
【図２６】
2007091558.tif 000059
【図２７】
2007091558.tif 000060
【図２８】
2007091558.tif 000061
【図２９】
2007091558.tif 000062
【図３０】
2007091558.tif 000063
【図３１】
2007091558.tif 000064
【国際調査報告】
2007091558.tif 000065
2007091558.tif 000066
2007091558.tif 000067
2007091558.tif 000068